56

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?

4
  • 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. Commented Jun 6, 2014 at 5: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. Commented Jun 6, 2014 at 5: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. Commented Sep 25, 2017 at 22:08
  • 1
    I found the answers here very unsatisfactory, so I added an answer that I think is much better. Commented Sep 25, 2017 at 22:11

6 Answers 6

78

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 } ]

Sign up to request clarification or add additional context in comments.

Comments

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();

2 Comments

Yes! sort() changes the original array. The filter() function creates a filtered copy, leaving the original intact. see developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
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.
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.

1 Comment

An interesting feature of sort 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.
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

1 Comment

I will prefer this, I think it has a better performance than splice().sort()
2

Or from ES6:

const a = [1, 2, 3];
const b = [...a].sort();

1 Comment

oh yes! that's nice.
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]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.