How to sort strings in JavaScript
I have a list of objects I wish to sort based on a field attr
of type string. I tried using -
list.sort(function (a, b) {
return a.attr - b.attr
})
but found that -
doesn't appear to work with strings in JavaScript. How can I sort a list of objects based on an attribute with type string?
This should work:
if (item1.attr < item2.attr)
return -1
if ( item1.attr > item2.attr)
return 1
return 0
Even better, you can use String.prototype.localeCompare
:
return item1.attr.localeCompare(item2.attr);
An updated answer (October 2014)
I was really annoyed about this string natural sorting order so I took quite some time to investigate this issue. I hope this helps.
Long story short
localeCompare()
character support is badass, just use it. As pointed out by Shog9
, the answer to your question is:
return item1.attr.localeCompare(item2.attr);
Bugs found in all the custom javascript "natural string sort order" implementations
There are quite a bunch of custom implementations out there, trying to do string comparison more precisely called "natural string sort order"
When "playing" with these implementations, I always noticed some strange "natural sorting order" choice, or rather mistakes (or omissions in the best cases).
Typically, special characters (space, dash, ampersand, brackets, and so on) are not processed correctly.
You will then find them appearing mixed up in different places, typically that could be:
When one would have expected special characters to all be "grouped" together in one place, except for the space special character maybe (which would always be the first character). That is, either all before numbers, or all between numbers and letters (lowercase & uppercase being "together" one after another), or all after letters.
My conclusion is that they all fail to provide a consistent order when I start adding barely unusual characters (ie. characters with diacritics or charcters such as dash, exclamation mark and so on).
Research on the custom implementations:
Natural Compare Lite
https://github.com/litejs/natural-compare-lite : Fails at sorting consistently https://github.com/litejs/natural-compare-lite/issues/1 and http://jsbin.com/bevututodavi/1/edit?js,console , basic latin characters sorting http://jsbin.com/bevututodavi/5/edit?js,console Natural Sort
https://github.com/javve/natural-sort : Fails at sorting consistently, see issue https://github.com/javve/natural-sort/issues/7 and see basic latin characters sorting http://jsbin.com/cipimosedoqe/3/edit?js,console Javascript Natural Sort
https://github.com/overset/javascript-natural-sort : seems rather neglected since February 2012, Fails at sorting consistently, see issue https://github.com/overset/javascript-natural-sort/issues/16 Alphanum
http://www.davekoelle.com/files/alphanum.js , Fails at sorting consistently, see http://jsbin.com/tuminoxifuyo/1/edit?js,console Browsers' native "natural string sort order" implementations via localeCompare()
localeCompare()
oldest implementation (without the locales and options arguments) is supported by IE6+, see http://msdn.microsoft.com/en-us/library/ie/s4esdbwz(v=vs.94).aspx (scroll down to localeCompare() method). The built-in localeCompare()
method does a much better job at sorting, even international & special characters. The only problem using the localeCompare()
method is that "the locale and sort order used are entirely implementation dependent". In other words, when using localeCompare such as stringOne.localeCompare(stringTwo): Firefox, Safari, Chrome & IE have a different sort order for Strings.
Research on the browser-native implementations:
Difficulty of "string natural sorting order"
Implementing a solid algorithm (meaning: consistent but also covering a wide range of characters) is a very tough task. UTF8 contains more than 2000 characters & covers more than 120 scripts (languages). Finally, there are some specification for this tasks, it is called the "Unicode Collation Algorithm", which can be found at http://www.unicode.org/reports/tr10/ . You can find more information about this on this question I posted https://softwareengineering.stackexchange.com/questions/257286/is-there-any-language-agnostic-specification-for-string-natural-sorting-order
Final conclusion
So considering the current level of support provided by the javascript custom implementations I came across, we will probably never see anything getting any close to supporting all this characters & scripts (languages). Hence I would rather use the browsers' native localeCompare() method. Yes, it does have the downside of beeing non-consistent across browsers but basic testing shows it covers a much wider range of characters, allowing solid & meaningful sort orders.
So as pointed out by Shog9
, the answer to your question is:
return item1.attr.localeCompare(item2.attr);
Further reading:
Thanks to Shog9's nice answer, which put me in the "right" direction I believe
Simplest Answer with ECMAScript 2016
list.sort((a, b) => (a.attr > b.attr) - (a.attr < b.attr))
Or
list.sort((a, b) => +(a.attr > b.attr) || -(a.attr < b.attr))
链接地址: http://www.djcxy.com/p/75188.html
上一篇: Javascript包含大小写不敏感