Use String.prototype.localeCompare as per your example:
list.sort(function (a, b) {
return ('' + a.attr).localeCompare(b.attr);
})
We force a.attr to be a string to avoid exceptions. localeCompare has been supported since Internet Explorer 6 and Firefox 1. You may also see the following code used that doesn't respect a locale:
if (item1.attr < item2.attr)
return -1;
if ( item1.attr > item2.attr)
return 1;
return 0;
Answer from Shog9 on Stack OverflowUse String.prototype.localeCompare as per your example:
list.sort(function (a, b) {
return ('' + a.attr).localeCompare(b.attr);
})
We force a.attr to be a string to avoid exceptions. localeCompare has been supported since Internet Explorer 6 and Firefox 1. You may also see the following code used that doesn't respect a locale:
if (item1.attr < item2.attr)
return -1;
if ( item1.attr > item2.attr)
return 1;
return 0;
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.
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:
- some will be between the uppercase 'Z' and the lowercase 'a'
- some will be between the '9' and the uppercase 'A'
- some will be after lowercase 'z'
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 (i.e., characters with diacritics or characters 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 Internet Explorer 6 and later, see Legacy Microsoft Edge developer documentation (scroll down to the localeCompare() method).
The built-in localeCompare() method does a much better job at sorting, even international and 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, and Internet Explorer have a different sort order for Strings.
Research on the browser-native implementations:
- http://jsbin.com/beboroyifomu/1/edit?js,console - basic Latin characters comparison with localeCompare() http://jsbin.com/viyucavudela/2/ - basic Latin characters comparison with localeCompare() for testing on Internet Explorer 8
- http://jsbin.com/beboroyifomu/2/edit?js,console - basic Latin characters in string comparison : consistency check in string vs when a character is alone
- String.prototype.localeCompare() - Internet Explorer 11 and later supports the new locales & options arguments
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. UTF-8 contains more than 2000 characters and covers more than 120 scripts (languages).
Finally, there are some specification for this tasks, it is called the "Unicode Collation Algorithm". You can find more information about this on this question I posted, Is there a 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 these characters and scripts (languages). Hence I would rather use the browsers' native localeCompare() method. Yes, it does have the downside of being non-consistent across browsers, but basic testing shows it covers a much wider range of characters, allowing solid and meaningful sort orders.
So as pointed out by Shog9, the answer to your question is:
return item1.attr.localeCompare(item2.attr);
Further reading:
- Is there a language-agnostic specification for "string natural sorting order"?
- How to sort strings in JavaScript
- Natural sort of alphanumerical strings in JavaScript
- Sort Array of numeric & alphabetical elements (Natural Sort)
- Sort mixed alpha/numeric array
- https://web.archive.org/web/20130929122019/http://my.opera.com/GreyWyvern/blog/show.dml/1671288
- https://web.archive.org/web/20131005224909/http://www.davekoelle.com/alphanum.html
- http://snipplr.com/view/36012/javascript-natural-sort/
- Sorting for Humans : Natural Sort Order
Thanks to Shog9's nice answer, which put me in the "right" direction I believe.
How do you sort numbers and number strings in Javascript? (From actual least to greatest
Sorting a mixed array of numbers and strings
I tried the sort method but it does sort from small to greatest. for example if I have 4, 33, 333 and use the sort method I get 33, 333, 4. So how do you actually sort from smallest to great numbers?
You can use array sort function:
var sortAlphabets = function(text) {
return text.split('').sort().join('');
};
STEPS
- Convert
stringtoarray - Sort
array - Convert back
arraytostring
Demo
Newer browsers support String.prototype.localeCompare() which makes sorting utf8 encoded strings really simple. Note that different languages may have a different order of characters. More information on MDN about localCompare.
function sortAlphabet(str) {
return [...str].sort((a, b) => a.localeCompare(b)).join("");
}
console.log(sortAlphabet("drpoklj")); // Logs: "djklopr"
If you only have to support ascii strings then the default sorting implementation will do.
function sortAlphabet(str) {
return [...str].sort().join("");
}