1

Seems very basic but I can't find any info on why is it happening.

I'm using the canonical MDN example to sort an array of objects and it seems the order in which the elements are passed into the compare callback is the opposite order. e.g.

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

// sort by value
items.sort(function (a, b) {
  console.log(a.name, b.name);
  return -1; // should keep the original order
});

// getting
// Sharpe Edward
// And Sharpe
// The And
// Magnetic The
// Zeros Magnetic

Again documentation says:

If compareFunction(a, b) returns less than 0, leave a and b unchanged.

What am I missing?

10
  • 4
    Your understanding of the documentation is incorrect. The sort comparator function must return consistent results for the two passed-in values, regardless of the order in which they're passed. In other words, sometimes a will be some value and b another, but the comparator may be called again with the values swapped. The return value must be consistent. Also, -1 does not mean "leave values in current order", is is an explicit indication that the first value (a) should go before the second (b). Commented May 19, 2021 at 16:08
  • 3
    for keeping the original order, you need to return zero. Commented May 19, 2021 at 16:09
  • 1
    That phrasing is pretty confusing tbh Commented May 19, 2021 at 16:11
  • 2
    @Pointy I checked the history of the MDN page, it was changed 3 months ago: github.com/mdn/content/commit/… . The earlier version was "If compareFunction(a, b) returns less than 0, sort a to an index lower than b" That is much more clearer and consistent with the greater than 0 part. Commented May 19, 2021 at 16:18
  • 1
    Here's the link to the issue: github.com/mdn/content/issues/2198 Commented May 19, 2021 at 16:37

1 Answer 1

4

The specification says:

If comparefn is not undefined and is not a consistent comparison function for the elements of this array (see below), the sort order is implementation-defined.

That's precisely your case. Your function is not consistent as it always returns -1 without actually comparing the two elements, so you shouldn't expect the result to be consistent (and you might find differences between browsers).

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

11 Comments

Thanks @Guerric. "Your function is not consistent as it always returns -1". Can you define "consistent" in this context? Always returning -1 seems pretty consistent to me :)
@krulik -1 means "a should go before b". The function has to be transitively consistent, so if a should go before b, and b should go before c, then a should also go before c. If the elements of the array are passed in a different order (like, b before a) then it fails that requirement.
@krulik well the actual algorithm used is not in the spec. If you think about how some sorting algorithms work, while it's in process the array will be "halfway" sorted, and there may have been some element interchanges (almost certainly). Once the array has started to be re-ordered, two elements that have already been compared may need to be compared again, but they may be in relatively different places in the partially-sorted array.
Your 2 first inputs are Edward and Sharpe, which are passed to the compare function as Sharpe, Edward (implementation defined) and your function says that Sharpe should go before Edward that's why it reverses
"implementation defined" were exactly the missing words for me (also the reasoning behind them)
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.