1

Having this Javascript code using sort:

var items = [
  { name: 'Edward', value: 21 },
  { name: 'Sharpe', value: 37 },
  { name: 'And', value: 45 },
  { name: 'The', value: -12 },
  { name: 'Magnetic' },
  { name: 'Zeros', value: 37 }
];

console.log(items.map(x=>x.name.toString()));

items.sort();

console.log(items.map(x=>x.name.toString()));

Even when we can see that in both browsers are compatible, the results are different:

Google Chrome 63

["Edward", "Sharpe", "And", "The", "Magnetic", "Zeros"]
["Edward", "Sharpe", "And", "The", "Magnetic", "Zeros"]

Microsoft Edge 25

["Edward", "Sharpe", "And", "The", "Magnetic", "Zeros"]
["Sharpe", "And", "The", "Magnetic", "Zeros", "Edward"]

Any idea of what is causing this or how it could be resolved?

You can test this behaviour in the following JSBin

Andy
  • 61,948
  • 13
  • 68
  • 95
Mario Levrero
  • 3,345
  • 4
  • 26
  • 57
  • 1
    What do you think you are actually sorting _by_ here? You’re not under the impression that you were sorting by the `name` properties, right? You are sorting using object comparison. – CBroe Feb 09 '18 at 11:01
  • What you are looking for is `items.sort((a.b) => a.name.localeCompare(b.name))` – Rajesh Feb 09 '18 at 11:04
  • @CBroe, The sort is by _nothing_. So I would expect a result like in Chrome. I'm using 'name' just to display the results. – Mario Levrero Feb 09 '18 at 11:12
  • You can not sort “by nothing”, that doesn’t even make sense. Quote from MDN, _“If [compareFunction is] omitted, the array is sorted according to each character's Unicode code point value, according to the string conversion of each element.”_ Your elements are objects here, so their string conversion will result in `[object Object]` for each one - so each of your items has _the same_ comparison value to begin with, none of them is “smaller” or “greater” than the other. So what result you get depends on whether the actual sorting algorithm used by the browser is a _stable_ one or not. – CBroe Feb 09 '18 at 11:24

1 Answers1

3

Any idea of what is causing this

Quote from MDN:

If [compareFunction is] omitted, the array is sorted according to each character's Unicode code point value, according to the string conversion of each element.

Your elements are objects here, so their string conversion will result in the string value [object Object] for each one - so each of your items has the same comparison value to begin with, none of them is “smaller” or “greater” than the other.

So what result you get depends on whether the actual sorting algorithm used by the browser is a stable one or not. (See also this question, What is stability in sorting algorithms and why is it important? )

https://medium.com/@fsufitch/is-javascript-array-sort-stable-46b90822543f:

Well, nowhere in the ES7 specification does it say whether the sort needs to be stable or not. In fact, it tries to be super abstract, allowing as much of the sort to be “implementation defined” as possible. This has resulted in different JS engines (across different browsers) taking different routes to implementing this spec, leading to inconsistent sort stability behavior.

.

or how it could be resolved?

You’d need to implement your own, stable sort algorithm.

But you would also need to use a self-written comparison function that properly compares your objects, because as said right now you are comparing only [object Object] to [object Object] ...

CBroe
  • 91,630
  • 14
  • 92
  • 150