Reputation: 1543
I'm having an issue with a JavaScript string comparison in a list sorting. It might sound silly but i haven't really found any real solution.
No problem sorting something as below:
A, B, C D ...
Issues come along sorting something like A1, A2, A3, A10, A11 Because it sorts them as following:
A1, A10, A11, A2, A3
I've tried to compare my two strings in 3 different ways.
1)
return a[key].localeCompare(b[key]);
2)
if ( a[key].toString() < b[key].toString() )
return -1;
if ( a[key].toString() > b[key].toString() )
return 1;
return 0;
3)
a = a[key].toString(), b = b[key].toString();
for (var i=0,n=Math.max(a.length, b.length); i<n && a.charAt(i) === b.charAt(i); ++i);
if (i === n) return 0;
return a.charAt(i) > b.charAt(i) ? -1 : 1;
Unfortunately, it keeps the wrong sort. Here there's an example where A1 compared with A10 is different than A2 compared with A10, whereas it should be the same.
Upvotes: 0
Views: 149
Reputation: 147
As Scott pointed out, the comparison basically happens on binary values. Either follow what Scott suggested or you can try this below code snippet (just added 2 lines to your code to check the length of strings to compare, specific for this scenario)
Note : I haven't tested this piece of code.
if(a[key].length < b[key].length) return -1;
if(a[key].length > b[key].length) return 1;
if ( a[key].toString() < b[key].toString() )
return -1;
if ( a[key].toString() > b[key].toString() )
return 1;
return 0;
Or else try formatting your input strings to same length. Eg A02 instead of A2
Upvotes: 0
Reputation: 49803
You are comparing strings, so they get sorted lexicographically, as if they were words in a dictionary, and not treating the digits as numbers (which is what you seem to want); to do that, you'd need to split the text & numeric portions and convert the latter as actual numbers to compare them.
Upvotes: 1