
This goes with https://github.com/SonarSource/SonarJS/pull/3873. `toSorted()` is a new, copying method for arrays that otherwise behaves the same as `sort()`.
61 lines
2.1 KiB
Plaintext
61 lines
2.1 KiB
Plaintext
== Why is this an issue?
|
|
|
|
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 `"éΔ"`.
|
|
|
|
```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.
|
|
|
|
|
|
=== Noncompliant code example
|
|
|
|
[source,javascript]
|
|
----
|
|
const myArray1 = [80, 3, 9, 34, 23, 5, 1];
|
|
myArray1.sort();
|
|
console.log(myArray1); // outputs: [1, 23, 3, 34, 5, 80, 9]
|
|
|
|
const myArray2 = [80, 3, 9, 34, 23, 5, 1];
|
|
const sorted = myArray2.toSorted();
|
|
console.log(sorted); // outputs: [1, 23, 3, 34, 5, 80, 9]
|
|
----
|
|
|
|
|
|
=== Compliant solution
|
|
|
|
[source,javascript]
|
|
----
|
|
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]
|
|
|
|
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]
|
|
----
|
|
|
|
|
|
|
|
ifdef::env-github,rspecator-view[]
|
|
|
|
'''
|
|
== Implementation Specification
|
|
(visible only on this page)
|
|
|
|
include::message.adoc[]
|
|
|
|
'''
|
|
== Comments And Links
|
|
(visible only on this page)
|
|
|
|
include::comments-and-links.adoc[]
|
|
endif::env-github,rspecator-view[]
|