Sort an Array without Mutation using JavaScript

avatar

Borislav Hadzhiev

Sun Nov 21 20212 min read

banner

Photo by Danka & Peter

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 operator (...) 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]

This 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 a numbers 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.

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 you want when working with number arrays, however it's exactly what you want when sorting string arrays.

An alternative, but also very commonly used approach is using 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 operator (...).

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 copied array, without mutating the original.

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

Join my newsletter

I'll send you 1 email a week with links to all of the articles I've written that week

Buy Me A Coffee