Sort an Array without Mutation using JavaScript

avatar

Borislav Hadzhiev

Last updated: Jul 29, 2022

banner

Check out my new book

Sort an Array without Mutation in JavaScript #

Use the spread operator (...) to sort an array without mutating the original, e.g. [...arr].sort(). The spread operator creates a shallow copy of the original array, on which you can call the sort() method without mutating the original array.

index.js
// ✅ for numbers const arr1 = [10, 5, 1, 7]; const result1 = [...arr1].sort((a, b) => a - b); console.log(result1); // 👉️ [1, 5, 7, 10] console.log(arr1); // 👉️ [10, 5, 1, 7] // ✅ for letters const arr2 = ['z', 'c', 'a', 'f']; const result2 = [...arr2].sort(); console.log(result2); // 👉️ ['a', 'c', 'f', 'z'] console.log(arr2); // 👉️ ['z', 'c', 'a', 'f']

We used the spread syntax (...) to unpack the values of an array into a new array.

index.js
const a = [1, 2, 3]; const b = [...a]; console.log(b); // 👉️ [1, 2, 3]

The spread syntax (...) allows us to create a shallow copy of the original array, on which we can call the Array.sort method.

The examples show how to sort number and string arrays without mutating the original.

When sorting a numbers array, we have to pass a function to the sort() method, whereas with strings, we don't.

The parameter we passed to the method in the first example is a function that defines the sort order.

index.js
const arr1 = [10, 5, 1, 7]; const result1 = [...arr1].sort((a, b) => a - b); console.log(result1); // 👉️ [1, 5, 7, 10] console.log(arr1); // 👉️ [10, 5, 1, 7]
If the function parameter is not provided to the sort method, the array elements get converted to strings and sorted according to their UTF-16 code unit values.

This is not what we want when working with number arrays, however it's exactly what we want when sorting string arrays.

An alternative, but also very common approach is to use the Array.slice method.

Sort an Array without Mutation using slice() #

To sort an array, without mutating the original array:

  1. Call the slice() method on the array to get a copy.
  2. Call the sort() method on the copied array.
  3. The sort method will sort the copied array, without mutating the original.
index.js
// ✅ for numbers const arr3 = [8, 4, 12]; const result3 = arr3.slice().sort((a, b) => a - b); console.log(result3); // 👉️ [4, 8, 12] console.log(arr3); // 👉️ [8, 4, 12] // ✅ for letters const arr4 = ['z', 'c', 'a', 'f']; const result4 = arr4.slice().sort(); console.log(result4); // 👉️ ['a', 'c', 'f', 'z'] console.log(arr4); // 👉️ ['z', 'c', 'a', 'f']

The slice() method can be used to create a shallow copy of an array, just like the spread syntax (...).

When no parameters are passed to the slice method, it returns a shallow copy of the array.

We can then call the sort method on the copy to not mutate the original.

Which approach you pick is a matter of personal preference. I'd go with the spread syntax (...) since I find it more direct.

Further Reading #

Use the search field on my Home Page to filter through my more than 3,000 articles.