Spaceship Operator
For what it's worth, for most practical purposes, `arr.sort((a, b) => b -
a))` works well enough. (The only thing it doesn't work well with are NaNs, but in practice, those almost never occur.)
On Tue, Jun 27, 2017 at 4:13 PM, Isiah Meadows <isiahmeadows at gmail.com> wrote:
For what it's worth, for most practical purposes,
arr.sort((a, b) => b - a))
works well enough. (The only thing it doesn't work well with are NaNs, but in practice, those almost never occur.)
Don't numeric comparison operators typically sort -0 before +0?
((a,b)=>b-a) is also problematic for an array that contains two or
more infinite values with the same sign and one or more finite values since isNaN(Infinity-Infinity). That NaN from the comparator can be triggered or not based on details of the sorting algo and the precise placement on the Infinities.
Inline
On Tue, Jun 27, 2017, 16:19 Mike Samuel <mikesamuel at gmail.com> wrote:
On Tue, Jun 27, 2017 at 4:13 PM, Isiah Meadows <isiahmeadows at gmail.com> wrote:
For what it's worth, for most practical purposes,
arr.sort((a, b) => b - a))
works well enough. (The only thing it doesn't work well with are NaNs, but in practice, those almost never occur.)Don't numeric comparison operators typically sort -0 before +0?
In JavaScript, not if I recall correctly. The only places where signed zeroes are relevant is in division.
((a,b)=>b-a) is also problematic for an array that contains two or more infinite values with the same sign and one or more finite values since isNaN(Infinity-Infinity). That NaN from the comparator can be triggered or not based on details of the sorting algo and the precise placement on the Infinities.
Infinities have also been similarly rare for me except in isolation.
On Tue, Jun 27, 2017 at 4:29 PM, Isiah Meadows <isiahmeadows at gmail.com> wrote:
Inline
On Tue, Jun 27, 2017, 16:19 Mike Samuel <mikesamuel at gmail.com> wrote:
On Tue, Jun 27, 2017 at 4:13 PM, Isiah Meadows <isiahmeadows at gmail.com> wrote:
For what it's worth, for most practical purposes, `arr.sort((a, b) => b
a))` works well enough. (The only thing it doesn't work well with are NaNs, but in practice, those almost never occur.)
Don't numeric comparison operators typically sort -0 before +0?
In JavaScript, not if I recall correctly. The only places where signed zeroes are relevant is in division.
There are others. Math.sign(-0)
((a,b)=>b-a) is also problematic for an array that contains two or more infinite values with the same sign and one or more finite values since isNaN(Infinity-Infinity). That NaN from the comparator can be triggered or not based on details of the sorting algo and the precise placement on the Infinities.
Infinities have also been similarly rare for me except in isolation.
Fair enough. There are more builtins that produce Infinity though. JSON.parse('1e1000')
Le 27 juin 2017 à 22:19, Mike Samuel <mikesamuel at gmail.com> a écrit :
On Tue, Jun 27, 2017 at 4:13 PM, Isiah Meadows <isiahmeadows at gmail.com> wrote:
For what it's worth, for most practical purposes,
arr.sort((a, b) => b - a))
works well enough. (The only thing it doesn't work well with are NaNs, but in practice, those almost never occur.)Don't numeric comparison operators typically sort -0 before +0?
((a,b)=>b-a) is also problematic for an array that contains two or more infinite values with the same sign and one or more finite values since isNaN(Infinity-Infinity). That NaN from the comparator can be triggered or not based on details of the sorting algo and the precise placement on the Infinities.
When the comparison function produces NaN, it is treated the same way as 0; so no it is not a problem for infinities.
More precisely, because (Infinity - Infinity)
is NaN, Infinity
is treated as “equal” to Infinity
, which is correct.
It is an issue with NaN
, because NaN
will be treated as “equal” to any value.
PHP, Ruby, Groovy have spaceship operator
<=>
. In short, this operator compares values and returns1
,-1
,0
.ECMAScript spec's
TypedArray#sort
has the default comparison part like following code, so I think it's useful that appending spaceship operator to ECMAScript like it.www.ecma-international.org/ecma-262/8.0/#sec-%typedarray%.prototype.sort
function isPlusZero(val) { return val === 0 && 1 / val === Infinity; } function defaultCompare(x, y) { const [isNaN_x, isNaN_y] = [Number.isNaN(x), Number.isNaN(y)]; if(isNaN_x && isNaN_y) return 0; if(isNaN_x) return 1; if(isNaN_y) return -1; if(x < y) return -1; if(x > y) return 1; if(x === 0 && y === 0) { const [isPlusZero_x, isPlusZero_y] = [isPlusZero(x), isPlusZero(y)]; if(!isPlusZero_x && isPlusZero_y) return -1; if(isPlusZero_x && !isPlusZero_y) return 1; } return 0; }
// NaN behave like the biggest number NaN <=> NaN // 0 NaN <=> 42 // 1 42 <=> NaN // -1 Infinity <=> NaN // -1 // finite 10 <=> 10 // 0 -1 <=> 10 // -1 10 <=> -1 // 1 // 0, -0 are not the same -0 <=> 0 // -1 0 <=> -0 // 1
Use cases
// Array#sort can use TypedArray#sort default comparison part [10, 5, NaN, -1].sort((a, b) => a <=> b); // [-1, 5, 10, NaN] // desc order new Float64Array([10, 5, NaN, -1]).sort((a, b) => -(a <=> b)); // [NaN, 10, 5, -1]
Problems
TypedArray#sort
default comparison part has nostring
order function."abc" <=> "def" // same as "abc".localeCompare("def") ? "abc" <=> 42 // same as "abc".localeCompare("42") ?
I found the reference to spaceship operator in ES Discuss. It has Already discussed in TC39 meeting?
esdiscuss.org/topic/informative-notes#content