4
var a = ['a100', 'a1', 'a10'];
a.sort();

This logs: ["a1", "a10", "a100"]

var a = ['f_a100_', 'f_a1_', 'f_a10_'];
a.sort();

But this logs: ["f_a100_", "f_a10_", "f_a1_"]

Can you please advise me why is that?

5
  • 4
    Because it is a string sort... Commented Jan 21, 2014 at 17:08
  • 1
    its either sorcery or witchcraft but definitely not both Commented Jan 21, 2014 at 17:09
  • 1
    Of course, but there is no difference besides the prefix... In each example this is a default string sort. Commented Jan 21, 2014 at 17:10
  • 2
    @gazdac There's also a postfix in the latter example... 0 comes before _... Commented Jan 21, 2014 at 17:12
  • Teemu pointed to the difference I missed, other answers are not directly related to the question. Commented Jan 21, 2014 at 17:14

5 Answers 5

4

Array.sort sorts value by converting the item to string and then doing a lexicographical sort.

Now, by lexicographical sorting all that they mean is that they compare the string characters one by one till a non matching character is found. The position of the non matching character in the character-set (where letters are ordered alphabetically) decides the rank of the string.

f_a100_
    ^
f_a1_
    ^
f_a10_
    ^

See the first non matching character. Here _ is greater than 0 (check their ascii codes) so f_a100_ and f_a10_ comes above f_a1_. Now between those two we go to the next character

f_a100_
     ^
f_a10_
     ^

Here, applying the same logic f_a100_ comes first. So the final order is ["f_a100_", "f_a10_", "f_a1_"]

This sorting order would seem logical for simple strings. But for certain other cases like yours it works weirdly because of the way the charsets are arranged. To get a desired behaviour you should write your own compare function that strips out the number part and return a positive, negative or 0 value as shown in the example.

Sign up to request clarification or add additional context in comments.

Comments

1

Javascript sorting is string based:

var a = ['a100', 'a1', 'a10'];
a.sort();

Will return:

["a1", "a10", "a100"]

Because of string comparison: "a1" < "a10" < "a100". In the other example, "f_a100_" < "f_a10_" because "0" < "_", and "f_a10_" < "f_a1_" for the same reason.

Indeed this:

[15, 13, 8].sort();

will return:

[13, 15, 8]

This is something a little weird, but that's how it's designed. If you want to change the ordering criteria you can pass a function as a parameter. E.g. (From here)

var points = [40,100,1,5,25,10];
points.sort(function(a,b){return a-b});

3 Comments

"This is something a little weird",... define weird :).
Guys, tnx, I know all that, but I missed suffixed underscore sign, as I previously said. I'm really tired, so I'm really glad someone spotted that :)
@Dalorzo: Hehe "weird" maybe is not the best word, but... I'd expect the interpreter could "detect" it's an array of integers and used the appropriate comparison function, like Ruby for example. But I can live with that.
0

The javascript sort function does sorting alphanumerically not arithmetically so you get the results such. See this question that is almost same with yours Array Sort in JS

Comments

0

In the first case "a1" < "a10" because when comparing two strings the "a1" portion matches but then it decides that "a1" has a shorter length.

But in the second case "f_a1_" > "f_a10_", because when comparing these two the "f_a1" portion matches and then "_" is compared to "0". And '_' > '0' because they are compared by their ascii value.

Comments

0

Array.sort uses string sorting (even if the array is a list of numbers).

The sorting you're looking for is known as natural order sorting. In this sorting numbers are treated as numbers, 100 comes after 10, 2 comes before 10 etc.

JavaScript does not natively have a natsrt. I have written my own implementation but it's quite involved. Here is a reference implementation: http://phpjs.org/functions/strnatcmp/

If you just need to sort strings of the form f_a[0-9]+_ you can write a regular expression to extract the number part.

1 Comment

I'm not looking for it, just wanted to know why is that sorted like it was :) But thanks anyways

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.