-2

I am having seemingly inconsistent results trying to sort arrays of strings using the sort method, both with and without passing sort() a function:

function sortThese(strArr) { 

    var words = [];
    for (var i = 0; i < strArr.length; i++) {
        words.push(String(strArr[i].length + "," + strArr[i]));
    }

    words = words.sort();
    console.log(words);
}

sortThese(["battt","catt","mat"]);
sortThese(["as","assssvvvvt","affggg"]);

in this case my results are:

["3,mat", "4,catt", "5,battt"]
["10,assssvvvvt", "2,as", "6,affggg"]

so it appears that the method is seeing my "10" as "1."

How do I make it see the value as 10?

Futher, if I pass sort this function:

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

the result is not sorted:

["4,catt", "5,battt", "3,mat"]
["2,as", "10,assssvvvvt", "6,affggg"]

I would love some clarification regarding how I should expect the sort method to behave, and how to make it sort these strings! Thank you

Nate Higgins
  • 2,104
  • 16
  • 21
adrichman
  • 1,215
  • 10
  • 17
  • possible duplicate of [Natural Sorting algorithm](http://stackoverflow.com/questions/34518/natural-sorting-algorithm) – JJJ Oct 11 '13 at 17:41

2 Answers2

1

The "10" comes before "3", because you've made it into a string (ie, "1" comes before "3"). If you want to sort by length, you could use the sort function to compare lengths:

words.sort(function(a, b) { return a.length > b.length; });

Fiddle

You could also create a nested object array, in order to hold a number and the string in each item:

var words = strArr.map(function(str) { 
    return { len: str.length, str: str } 
});
words.sort(function(a, b) { return a.len > b.len; });

(Of course, this second approach is unnecessary for the example case, but may be useful in other cases.)

Fiddle

McGarnagle
  • 101,349
  • 31
  • 229
  • 260
0

Sorting strings always uses alphabetical order, not numerical. Just imagine 0=A 1=B 2=C and so on. Letters are not connected as numbers, so everything starting with 1 (respective B) will be sorted before 2 (respective C). That's why you get 10,2,6. For 10, only the 1 counts.

Using a custom sort function is a good way to achieve this. But you cannot subtract strings. Extract the integer before and compare afterwards:

words = words.sort(function(a,b){
    //parseInt will read only the first numbers and discard the letters after this
    return parseInt(a) - parseInt(b) 
});
BenMorel
  • 34,448
  • 50
  • 182
  • 322
Matthias Hauert
  • 107
  • 1
  • 11