4
var city = [{
"city":"London"
},{
"city":"Wales"
}
,{
"city":"Atom"
}
,{
"city":"Bacelona"
}];

city.sort(function(a,b){
return a.city - b.city;
})

console.log(city)

Not sure what's wrong with above code, why it isn't sort? my logic seems fine.

Jennifer
  • 905
  • 9
  • 20

2 Answers2

2

Return in the function for strings:

return a.city.localeCompare(b.city);

var city = [{ "city": "London" }, { "city": "Wales" }, { "city": "Atom" }, { "city": "Bacelona" }];

city.sort(function (a, b) {
    return a.city.localeCompare(b.city);
});

document.write('<pre>' + JSON.stringify(city, 0, 4) + '</pre>');
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
  • localCompare versus `>`, which one is better? – Jennifer Apr 01 '16 at 07:04
  • `localeCompare` is slower but easier to use since it outputs -1, 0, and 1 like a sort function should. also also need to be careful not to call it on any non-string properties, or else it will likely throw: `(6).localeCompare("A")`. – dandavis Apr 01 '16 at 07:06
  • i would go for localeCompare, as my answer suggest. the solution with smaller than is tricky because it returns only two values instead of thee (-1, 0, 1). – Nina Scholz Apr 01 '16 at 07:09
2

You can't use - operator on strings, they are only for numbers. You need to use <, >, <= or >= for lexigraphical order.

Nina Scholz's answer is very useful when you work on non-English words, and it works on English words.

Simply changing the - to > would make the code work:

var city = [{
    "city": "London"
}, {
    "city": "Wales"
}, {
    "city": "Atom"
}, {
    "city": "Bacelona"
}];

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

console.log(city);
Jamie
  • 1,096
  • 2
  • 19
  • 38
  • this would be unstable on any duplicated values, in which a `0` should be returned. it's also technically a quirk to not return one of `[-1,0,1]` in a sort(), and it not guaranteed to work everywhere... – dandavis Apr 01 '16 at 06:59
  • @dandavis, if the city is duplicated, then the order of the two (or more) objects cannot be determined like this. You can include other conditions after this, for example, `return (a.city > b.city) || (a.latitude > b.latitude)` – Jamie Apr 01 '16 at 07:00
  • nah, you just need something like `return a.city > b.city ? 1 : (a.city==b.city?0:-1);` to avoid shuffling a dupe. objects with duplicate properties and more than one visible prop can simply use the existing index position as a 2nd criterion to achieve stability: http://stackoverflow.com/a/2085225/2317490 – dandavis Apr 01 '16 at 07:01
  • You're right. A number is needed according to the Mozilla documentation – Jamie Apr 01 '16 at 07:04