5
[
{"tag":"fujairah","count":1},
{"tag":"worldwide","count":3},
{"tag":"saudi","count":1},
{"tag":"miami","count":1},
{"tag":"rwo-dealer","count":7},
{"tag":"new york","count":2},
{"tag":"surabaya","count":1},
{"tag":"phillippines","count":1},
{"tag":"vietnam","count":1},
{"tag":"norway","count":1},
{"tag":"x","count":1}
].sort(function(a,b){return a.tag>b.tag})

Sorting an array of 10 objects works fine, once the number of objects exceeds 10, the sort fails in Chrome for Mac. Safari fails at any array size. (Works fine in Firefox)

What is the correct way of sorting arrays of objects by javascript?

2
  • I tested this problem again in 29.4.2018 on Mac in Firefox, Safari and Chrome and comparing strings with a simple expression works fine in newer browsers. Commented Apr 29, 2018 at 12:54
  • However, to be on the safe side, the simple comparing of values should be used only with numbers. See: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… Commented Apr 29, 2018 at 13:05

2 Answers 2

3

It doesn't matter the number of items, it may be just your case. It's just that's not the correct way to implement a sorting function. You should return 1 (or any positive value, if the first item is "greater" than the second), -1 (or any negative value) or 0 (if the items are equal). Try something like this:

.sort(function(a, b) {
    return a.tag > b.tag ? 1 : (a.tag < b.tag ? -1 : 0);
});

The parentheses around the last ternary operator aren't actually necessary.

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

4 Comments

It seems that this is a chrome javascript engine bug.Here's a fiddle[jsfiddle.net/jqsgcnt3/] that I wrote that shows sort is not working correctly if there are more than 10 objects in an array(in my example all items have same order so I assert that original sort should not be changed)
@Beatles1692 That's not a bug, Chrome works according to the spec, which does not force vendors to keep the elements in order (see also here). Annoying, but correct. Anyway, this subject is off topic.
The answer does not address the true origin of the problem of "Sorting an array of 10 objects works fine, once the number of objects exceeds 10, the sort fails" thus it is not valid in similar scenarios with different order key (as my fiddle shows).I think the answer would be more helpful if it also addresses the unstable nature of javascript arrays.
@Beatles1692 You're assuming things with no justification. The question was "What is the correct way of sorting arrays of objects by javascript?", and I've answered exactly to that, which is the "true origin of the problem". The sorting function was wrong, it's as simple as that. Whether OP wants to know the reason why sort swaps two "equivalent" elements or not depending on the browser, they should open a new question or at least ask for a clarification.
2

As noted in the accepted answer the only way to assure the compare function results in expected sort order is to return a number other than 0.

The reasoning for this though is important and should be noted for reference purposes. ECMA standards allow for browser implementations to be unstable. As such there can be no expectation that a function returning 0 will result in the original sort order.

http://www.ecma-international.org/ecma-262/5.1/#sec-15.4.4.11

The sort is not necessarily stable (that is, elements that compare equal do not necessarily remain in their original order). If comparefn is not undefined, it should be a function that accepts two arguments x and y and returns a negative value if x < y, zero if x = y, or a positive value if x > y.

Now for Chrome (and others). Browsers can use whatever sort algorithms they want based on whatever criteria they choose. Since certain algorithms are more efficient based on array size the vendor can choose to change the underlying algo dynamically based on the array size. This is why you're seeing this behavior.

At the time of writing the Chromium source uses length <= 10 as the deciding factor.

https://cs.chromium.org/chromium/src/v8/src/js/array.js?l=707&rcl=9c7cccf55126353a101f194bcf1f8826bc263804

function InnerArraySort(array, length, comparefn) {
  // In-place QuickSort algorithm.
  // For short (length <= 10) arrays, insertion sort is used for efficiency.
  ...
  if (to - from <= 10) {
    InsertionSort(a, from, to);
    return;
  }
 ...

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.