Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript: sort array of objects with Ukrainian letters

I have an array of objects:

var countries = [
    {'id': 35, 'name': 'Перу'},
    {'id': 45, 'name': 'Індія'},
    {'id': 55, 'name': 'Єгипет'},
    {'id': 65, 'name': 'Албанія'},
]

I need to sort it by name. Here is my algorithm:

function mySort(s1, s2) {
    return s1.name.toString().localeCompare(s2.name.toString());
}

var sorted = countries.sort(mySort);

// result (incorrect)
sorted = [
    {'id': 55, 'name': 'Єгипет'},
    {'id': 45, 'name': 'Індія'},
    {'id': 65, 'name': 'Албанія'},
    {'id': 35, 'name': 'Перу'},
]

// must be
sorted = [
    {'id': 65, 'name': 'Албанія'},
    {'id': 55, 'name': 'Єгипет'},
    {'id': 45, 'name': 'Індія'},
    {'id': 35, 'name': 'Перу'},
]

What am I doing wrong?

Here is example on jsfiddle and screenshot of my result in jsfiddle.

enter image description here

Thanks!

EDIT:

I've found that only Google chrome sorts incorrect: FireFox and Opera do it correct.

like image 588
Vitalii Ponomar Avatar asked Jun 18 '26 05:06

Vitalii Ponomar


1 Answers

Your code is working as you expected for me.

It doesn't make a functional difference, but you don't need to call .toString() on something that is already a String. I.E., you can simplify mySort to this:

var mySort = function(s1, s2){
    return s1.name.localeCompare(s2.name);
}

(I also prefer to declare all functions as variables, as they're all the same in JavaScript - so they should be handled consistently.)

However, as to answer why this may not be working for you, per http://msdn.microsoft.com/en-us/library/windows/apps/62b7ahzy%28v=vs.94%29.aspx (interestingly, MDN's page doesn't say anything about this) - emphasis mine:

The localeCompare performs a locale-sensitive string comparison of the stringVar and the stringExp and returns -1, 0, or +1, depending on the sort order of the system default locale.

If you want something that will sort purely on the character codes without regards to the user's locale, you could use this instead:

var mySort = function(s1, s2){
    if(s1 == s2){
      return 0;
    }
    return s1.name > s2.name;
}

This will sort consistently, regardless of the client's or user's settings / preferences - but it also returns the results you classified as incorrect.


Edit: As you mentioned that the behavior you're observing is specific to Google Chrome, this appears to be a known issue in Chrome, and is being tracked at http://code.google.com/p/v8/issues/detail?id=459.

like image 177
ziesemer Avatar answered Jun 20 '26 19:06

ziesemer



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!