53

I have that code:

arr = arr.sort(function (a, b) {
    return a.time>b.time
})

Do I need to redefine arr or it is possible just to call sort function? like this:

arr.sort(function (a, b) {
    return a.time>b.time
})

Will the sort and filter functions change the original array?

Web_Designer
  • 72,308
  • 93
  • 206
  • 262
Prosto Trader
  • 3,471
  • 3
  • 31
  • 52
  • 1
    i've tried, I can't inderstand why it doesnt work sometimes. Is there a problem in my code or I'm misusing .sort function. – Prosto Trader Jun 06 '14 at 05:52
  • 2
    both will work. as the `sort` changes the array. But the comparator function will work based on the return value of (+n, 0, -n) not `boolean`. Please change the comparator. – Kamrul Jun 06 '14 at 05:53
  • I really don't see what's wrong with the question, but yes it's something that can be tested using the === operator, before and after sort. – Alexander Mills Sep 25 '17 at 22:08
  • 1
    I found the answers here very unsatisfactory, so I added an answer that I think is much better. – Alexander Mills Sep 25 '17 at 22:11

6 Answers6

73

Use slice() to sort a copy of the original array.

var arr =[{time:4},{time:3},{time:6}];

arr.sort(function (a, b) {
  return a.time-b.time;
});

will mutate the original array and returns :

[ { time: 3 }, { time: 4 }, { time: 6 } ]

and console.log(arr) returns

[ { time: 3 }, { time: 4 }, { time: 6 } ]

but

var arr =[{time:4},{time:3},{time:6}];
arr.slice().sort(function (a, b) {
  return a.time-b.time;
});

returns

[ { time: 3 }, { time: 4 }, { time: 6 } ]

but will not affect the original array.

console.log(arr) returns

[ { time: 4 }, { time: 3 }, { time: 6 } ]

LexJacobs
  • 2,483
  • 15
  • 21
23

It's a decent question, and let's answer it properly:

const a = [1, 2, 3];
const b = a.sort();
console.log(a === b); // true

there is your answer. The === operator for objects will compare memory locations, so it's the same object in memory.

Which is a shame because it would be better if sort created a new array (immutability etc), but in many languages it does not return a new array, but the same array (reordered).

So if you want it to be immutable, you can do:

const a = [1, 2, 3];
const b = a.slice(0).sort();
Max Base
  • 639
  • 1
  • 7
  • 15
Alexander Mills
  • 90,741
  • 139
  • 482
  • 817
  • 5
    Yes! sort() changes the original array. The filter() function creates a filtered copy, leaving the original intact. see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter – Bill B May 07 '19 at 17:28
  • 1
    Actually, I quite like that it mutates the original. Because that, you can deal with and work around that. You can't work around "I want to have this array sorted so that the existing references get the updated data" but they don't automatically. Imagine if `arr.push(4,5,6)` didn't mutate the original. That would be a nightmare. You'd have to rely solely on `arr = arr.concat([4,5,6])`, and you still couldn't update references. – RoboticRenaissance Dec 30 '20 at 18:31
10

It sorts the array in place (modifying the array). From MDN:

The sort() method sorts the elements of an array in place and returns the array. The sort is not necessarily stable. The default sort order is according to string Unicode code points.

jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • An interesting feature of [*sort*](http://ecma-international.org/ecma-262/5.1/#sec-15.4.4.11) is that `"undefined property values always sort to the end of the result, followed by non-existent property values"`, so it effectively changes a sparse arrays to compact but keeps the original length. – RobG Jun 06 '14 at 06:14
5

Yes it modifies the original array.

const a = [1, 2, 3];
const b = a.sort();
const c = [...a].sort(); //es6 feauture similar to slice(0)
console.log(a === b); // true
console.log(a === c);//false
SUSEENDHAR LAL
  • 141
  • 2
  • 3
1

Or from ES6:

const a = [1, 2, 3];
const b = [...a].sort();
Adrian Bartholomew
  • 2,506
  • 6
  • 29
  • 37
1

Will the sort and filter functions change the original array

For sort() method, Answer is Yes but for filter() method answer is No.

Let me explain with an example :

// Original Array
const arr = [5, 4, 3, 2, 1];

// Sorting array values and assigned in a variable.
const sortedArr = arr.sort((a, b) => a-b);

// Original array modified.
console.log(arr); // [1,2,3,4,5]

// New variable with sorted array.
console.log(sortedArr); // [1,2,3,4,5]

To prevent the original array to get modified, We can use to[Operation] that return a new collection with the operation applied (This is currently at stage 3, will be available soon).

const arr = [5, 4, 3, 2, 1];

const sortedArr = arr.toSort((a, b) => a-b);

console.log(arr); // [5, 4, 3, 2, 1]

console.log(sortedArr); // [1, 2, 3, 4, 5]
Debug Diva
  • 26,058
  • 13
  • 70
  • 123