javascript-natural-sort icon indicating copy to clipboard operation
javascript-natural-sort copied to clipboard

['1.100', '1.10', '1.1', '1.54'] etc do not sort properly...

Open rubenstolk opened this issue 11 years ago • 7 comments

rubenstolk avatar Sep 23 '13 18:09 rubenstolk

Elements like 1.100 are implicitly coerced into floats so ['1.100', '1.10', '1.1'] are each interpreted as 1.1 when performing the sort comparison. In every browser but Chrome this will be "stable" e.g. they will remain in the same order prior to calling .sort(). I'm working through a simplified version that does less of the coercion and relies on the data type of the elements in the array supplied thus ['1.100', '1.10', '1.1'] would sort to a more "natural" ['1.1', '1.10', '1.100'].

overset avatar May 04 '15 09:05 overset

Hey @overset, did you ever come up with a solution for this?

I also have same problem where for example ['2.2 sec','1.9 sec','1.53 sec'] will sort as [1.9 sec, 1.53 sec, 2.2 sec]

harisb avatar Jan 26 '16 15:01 harisb

@harisb - I posted a fix for your example in v0.8.1

>>> ['2.2 sec','1.9 sec','1.53 sec'].sort(naturalSort)
["1.53 sec", "1.9 sec", "2.2 sec"]

I kept the float inference for strings that resemble numbers, e.g. ['1.100'] will still be coerced to 1.1. I'm still thinking it would be a good idea to rely on the input type instead of forcing coercion, e.g. if you send ['1.100'] it will chunk the string into 2 separate integers instead of force it to be a float. So we can then handle cases like:

>>> ['1.100','1.1','1.10'].sort(naturalSort)
["1.1", "1.10", "1.100"]
>>> [1.100, 1.1, 1.10].sort(naturalSort)
[1.1, 1.1, 1.1]

An original design feature was to coerce as many string values into their native data type as possible but this could be simplified and made more consistent.

overset avatar Jan 29 '16 11:01 overset

Awesome, that works! Thank you!

harisb avatar Jan 29 '16 14:01 harisb

Should this issue be closed?

sbichenko avatar Jun 10 '16 14:06 sbichenko

The fix for '2.2sec' breaks version numbers like '1.1a'.

Compare:

['1.1a', '1.1b', '1.10a'].sort(naturalSort)
['v1.1a', 'v1.1b', 'v1.10a'].sort(naturalSort)

The problem is determining the difference between a floating point number and a two-level version number. I think making floats be a 'word' on their own may work more intuitively. That way, '2.2 sec' would sort as expected, but things like '2.2sec' and '1.1a' would still sort as version numbers (even though to a human, the former is obviously not). My two cents.

macronx avatar Jul 11 '16 14:07 macronx

3eabc73718da57eaf00dafd2aef4fa9fdceac9bc breaks the unit test.

linquize avatar Oct 24 '16 14:10 linquize