I'm trying to sort an array of strings alphabetically, except for certain strings (e.g. "NA" and "Wild") that should always be placed last. The sorting priority should be sorted_values_alphabetically < "NA" < "Wild".
If we have the following array:
["Wild", "sit", "ipsum", "dolor", "NA", "amet", "lorem"];
I would like it to be sorted as:
["amet", "dolor", "ipsum", "lorem", "sit", "NA", "Wild"];
I was thinking something like
arr.sort(function(a,b) {
var aVal = a, bVal = b;
// Hack to make values < "NA" < "Wild"
if (aVal == "NA") aVal = "zzz" + aVal;
if (bVal == "NA") bVal = "zzz" + bVal;
if (aVal == "Wild") aVal = "zzzz" + aVal;
if (bVal == "Wild") bVal = "zzzz" + bVal;
return aVal.toLowerCase().localeCompare(bVal.toLowerCase());
});
But this probably wouldn't work for all Unicode characters.
I'm also interested in performant algorithms!
Just FYI, T. J. Crowder's algorithm is slightly more performant via jsPerf. Altohugh I prefer Halcyon's more concise approach!
So basically, all strings are less than "Wild", and all strings except "Wild" are less than "NA". The function you pass into sort should return a negative number if a < b, 0 if a == b, or a positive number if a > b. So you handle the special cases by returning appropriate values:
arr.sort(function(a,b) {
// Everything is less than "Wild"
if (a === "Wild") {
return 1; // a is greater than b
}
if (b === "Wild") {
return -1; // b is greater than a
}
// Everything else is less than "NA"
if (a === "NA") {
return 1; // a is greater than b
}
if (b === "NA") {
return -1; // b is greater than a
}
// Normal result
return a.toLowerCase().localeCompare(a.toLowerCase());
});
Live Example (source)
(Obviously, the detailed comments make that look longer than it actually is...)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With