78 lines
2.6 KiB
Plaintext
Raw Normal View History

== Why is this an issue?
2021-04-28 16:49:39 +02:00
The default sort order is alphabetic, rather than numeric, regardless of the types in the array. Specifically, even if an array contains only numbers, all values in it will be converted to strings and sorted lexicographically, for an order like this: 1, 15, 2, 20, 5.
Even to sort strings, the default sort order may give unexpected results. Not only does it not support localization, it also doesn't fully support Unicode, as it only considers UTF-16 code units. For example, in the code below, `"eΔ"` is surprisingly before and after `"éΔ"`.
2021-04-28 16:49:39 +02:00
```javascript
const name1 = '\u00e9\u0394'; // "éΔ"
const name2 = '\u0065\u0301\u0394'; // "éΔ" using Unicode combining marks
const name3 = '\u0065\u0394'; // "eΔ"
console.log([name1, name2, name3].sort()); // ["éΔ", "eΔ", "éΔ"], "eΔ" position is inconsistent
console.log([name1, name2, name3].sort((a, b) => a.localeCompare(b))); // ["eΔ", "éΔ", "éΔ"]
```
Fortunately the ``++sort++`` and ``++toSorted++`` methods allow you to pass an optional compare function to specify the sort order. When a compare function is supplied, the returned order depends on the return value of the compare function.
2021-04-28 16:49:39 +02:00
=== Noncompliant code example
2021-04-28 16:49:39 +02:00
2022-02-04 17:28:24 +01:00
[source,javascript]
2021-04-28 16:49:39 +02:00
----
const myArray1 = [80, 3, 9, 34, 23, 5, 1];
myArray1.sort();
console.log(myArray1); // outputs: [1, 23, 3, 34, 5, 80, 9]
2021-04-28 16:49:39 +02:00
const myArray2 = [80, 3, 9, 34, 23, 5, 1];
const sorted = myArray2.toSorted();
console.log(sorted); // outputs: [1, 23, 3, 34, 5, 80, 9]
2021-04-28 16:49:39 +02:00
----
=== Compliant solution
2021-04-28 16:49:39 +02:00
2022-02-04 17:28:24 +01:00
[source,javascript]
2021-04-28 16:49:39 +02:00
----
const myArray1 = [80, 3, 9, 34, 23, 5, 1];
myArray1.sort((a, b) => (a - b));
console.log(myArray1); // outputs: [1, 3, 5, 9, 23, 34, 80]
2021-04-28 16:49:39 +02:00
const myArray2 = [80, 3, 9, 34, 23, 5, 1];
const sorted = myArray2.toSorted((a, b) => (a - b));
console.log(sorted); // outputs: [1, 3, 5, 9, 23, 34, 80]
2021-04-28 16:49:39 +02:00
----
ifdef::env-github,rspecator-view[]
'''
== Implementation Specification
(visible only on this page)
=== Message
Provide a compare function to avoid sorting elements alphabetically.
'''
== Comments And Links
(visible only on this page)
=== on 27 Apr 2015, 12:57:27 Linda Martin wrote:
\[~ann.campbell.2] Assign for review and completion
=== on 28 Apr 2015, 13:28:08 Ann Campbell wrote:
Double-check my changes, please [~linda.martin]
Also, do you plan to raise this on all arrays, or limit it to when you can tell the array contains numbers?
=== on 29 Apr 2015, 09:16:26 Linda Martin wrote:
\[~ann.campbell.2] That's a good question. I think we'll do a first implementation and see what are the results and narrow the scope if too much FP shows up.
Reviewed.
endif::env-github,rspecator-view[]