Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

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

share|improve this question
 
possible duplicate of Natural Sorting algorithm –  Juhana Oct 11 '13 at 17:41
add comment

3 Answers

up vote 0 down vote accepted

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). Thats 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 substract strings. Extract the interger 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) 
});
share|improve this answer
add comment

Sort arrays instead of strings (keep the number as an actual number):

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

    words = words.sort(function(a,b) { return a[0] - b[0]; });
    console.log(words);
}
share|improve this answer
add comment

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

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.