5 ms·
So if I'm understanding correctly, JS sort sorts numbers by their string value? That's crazy. And it seems you have to add a compare function just to do a basic
by witty_username 11y ago
So if I'm understanding correctly, JS sort sorts numbers by their string value? That's crazy. And it seems you have to add a compare function just to do a basic operation to sort numbers.
- pjc50 11y agoThis is what happens when people try do to arithmetic in a typeless language. Javascript does not really have a number type; it just has values. Sometimes it infers that you want to do arithmetic on them. What is the correct order of the items ["2", 10, "banana", [[]], "", 1]? See also https://www.destroyallsoftware.com/talks/wat https://www.destroyallsoftware.com/talks/wat Bonus: sometimes you can get the same kind of behaviour in Excel when importing CSV.
- CJefferson 11y agoThe language isn't typeless. Other language (python and ruby, among many others) manage to integer and string comparision correct. It is trickier when someone compares "2" and 3, should we say it's invalid (my preference) or turn 2 into an integer, or 3 into a string? However, there is NO reason for there to be an issue comparing 1 and 11. This is just an unfortunately mistake that is too deeply baked into the language to fix at this point.
- xlm1717 11y agoWhere is the issue comparing 1 and 11? 1 < 11 still returns true. [11,1].sort((a,b) => a -b) still returns [1, 11].
- CJefferson 11y agoSorry, 1 and 11 isn't a problem in javascript. Insert two troublesome numbers :)
- evan_ 11y agoSeems like it should be up to you to come up with the troublesome numbers, since you're the one making claims.
- CJefferson 11y agoOh sorry, here we go. > [2] < [11] false Technically, a combination of integers and arrays. Still took me an afternoon to track down (it didn't occur to me javascript would work like that).
- gpvos 11y agoThen your knowledge of Javascript is sorely lacking. To make arrays work like that in Javascript would be very complicated, and counterintuitive to those who know how Javascript arrays work.
- CJefferson 11y agoI agree my knowledge of JavaScript is lacking, I just (wrongly) assumed arrays would act similarly to other languages. Obviously it's too late to change JavaScript now, but Iwould be interested to know why it would have been complicated to do this differently originally, and why it would be countintuitive? Is there anything I can read about this kind of thing?
- gpvos 11y agoYeah, that's more or less what you get when you hack a language together in 10 days... Arrays in JS are just a special case of objects, which are just name-value hashmaps. Although they usually have some optimizations in their internal implementation. I guess "Javascript: the Good Parts" is as good a place to start as any. It doesn't really go into the design decisions though.
- xlm1717 11y agoIt's not that it sometimes infers what you want to do. It's that it has defaults and if you want to do something besides the default, you need to specify what it is you want to do.
- bilalq 11y agoNo, this has nothing to do with how "JS sorts numbers". JavaScript sorts arrays by using a default comparator that runs .toString and compares unicode code point values (with safe handling around null/undefined). There is no concept of a typed number array in JS. There is just "Array", and an array's contents can be heterogenous. Imagine the following: ['a', 'c', 'b'].sort() // ['a','b','c'] ['a', 1].sort() // [1, 'a'] [1, ['foo'], {bar: 'baz'}, 'a', '2', null, undefined].sort() // [1, '2', {bar:'baz'}, 'a', ['foo'], null, undefined] The default comparator is one that can be run on any arbitrary array. It's up to you as a caller to specify that you'd like to sort by a different comparator. For a more detailed read, see: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
- abc_lisper 11y agoOne of the many reasons why I keep away from JS - it deviates from the norm without good reason, in arbitrary places.
- fenomas 11y ago> There is no concept of a typed number array in JS Note that nowadays there are indeed Int16Array, Float32Array, and so forth, and their sort methods work numerically like you'd expect.
- zaphar 11y agoAnd this kids is an example of a problem that compile time type checking can help with.
- toupeira 11y agoOr simply strong typing.
- tzs 11y ago> JavaScript sorts arrays by using a default comparator that runs .toString and compares unicode code point values (with safe handling around null/undefined). Is there an explanation somewhere of how they decided on that as the default comparator? My first inclination would have been to use "<" as the default comparator. That would sort purely numeric arrays numerically, and purely string arrays lexically, leaving only the case of arrays that mix numerical and non-numerical elements needing the programmer to step in and give an explicit comparator.
- fenomas 11y agoArray#sort sorts all elements by their converted string value. It may seem like a strange way to spec the language, but I'm not sure what would have been better. It wouldn't make sense for sort to have to run through the array checking types before it starts, or for it to dynamically change what kind of comparison it does depending on the types of each pair of elements being compared.
- xlm1717 11y agoIt might have made more sense to not have default behavior and force the user to specify how they want to sort. They could also have done what PHP did and provided several different .sort functions depending on how you want to sort.
- fenomas 11y agoI think ECMA4 proposed behavior flags, so you could do: arr1.sort( Array.NUMERICAL | Array.DESCENDING ) arr2.sort( Array.CASE_INSENSITIVE ) or similar.
- CJefferson 11y agoWhat would make sense (and what most other languages seem to do) is compare elementwise, using whatever ordering javascript would usually use. Therefore [X] < [Y] would be true whenever X<Y is true (for example)
- fenomas 11y agoThat would have undesirable side effects - e.g. it would mean the results of the sort are not necessarily specified. If the array contains NaN, for example, calling a sort like that would have different results depending on the order in which the elements are compared, which would likely vary by JS engine.
- CJefferson 11y agoI don't really understand your problem -- this is how array comparison is implemented in C++, Python, Ruby, Java (when using the default isComparable on most array-list types) and Haskell (from the languages I use frequently). Javascript is the only weird outlier.
- zeveb 11y ago> So if I'm understanding correctly, JS sort sorts numbers by their string value? That's crazy. It's JavaScript … it doesn't have to be sane; we'll use it anyway. I think that Erlang had the most elegant solution: it defines a total order over all objects (number < atom < reference < fun < port < pid < tuple < list < bit string). Of course, Erlang's 'strings' are pretty inelegant (they're just lists of integers, which are printed as strings if they happen to incidentally be valid characters), so I guess there's some Law of Conservation of Bogosity at play here.