Combined Comparison / "Spaceship" Operator (<=>) in Javascript?
Solution 1
As far as I know there is no such operator in JavaScript but you can use Math.sign() function:
Math.sign(a - b);
NOTE: As was mentioned in comments, Math.sign() is not currently supported by all browsers. Check for compatibility (MDN).
Solution 2
from: http://sabrelabs.com/post/48201437312/javascript-spaceship-operator
improved version:
function spaceship(val1, val2) {
if ((val1 === null || val2 === null) || (typeof val1 != typeof val2)) {
return null;
}
if (typeof val1 === 'string') {
return (val1).localeCompare(val2);
} else {
if (val1 > val2) {
return 1;
} else if (val1 < val2) {
return -1;
}
return 0;
}
}
Solution 3
Here is a one-liner for current js ES2020?:
const spaceship = (a, b) => (a ?? 0).toString().localeCompare((b ?? 0).toString());
Returns string comparison for everything.
Related videos on Youtube
Kaspar Lee
Updated on June 16, 2022Comments
-
Kaspar Lee almost 2 years
Ruby has something called a Combined Comparison or "Spaceship" Operator, it looks like this:
<=>
It does the following:
a <=> b := if a < b then return -1 if a = b then return 0 if a > b then return 1
Is there a similar Operator in Javascript? If not, how can I end up with the same result?
@madox2 suggested using
Math.sign(a - b)
, which works for number, but not arrays (to compare arrays you need to usearray.length
).It also does not work in Internet Explorer, Safari or all Mobile Browsers (see MDN)
@duques_l found a function here. It works very well, you can test it on JSFiddle
The only problem is if the strings are not comparable the function returns
-1
instead ofnil
Update: @duques_l changed the function a bit and now it works fine (I think so anyway, here is the JSFiddle):
function spaceship(val1, val2) { if ((val1 === null || val2 === null) || (typeof val1 != typeof val2)) { return null; } if (typeof val1 === 'string') { return (val1).localeCompare(val2); } else { if (val1 > val2) { return 1 } else if (val1 < val2) { return -1 } return 0; } }
-
Léo over 8 yearsdoesn't exist, but sabrelabs.com/post/48201437312/javascript-spaceship-operator
-
Kaspar Lee over 8 years@duques_l Interesting link. That function does seem to do just that!
-
-
Kaspar Lee over 8 yearsThis works for numbers, but not arrays (well, you have to use
array.length
). Clever solution though! -
Nina Scholz over 8 yearsif there is one, not in ie.
-
Kaspar Lee over 8 years@NinaScholz If there is one what?
-
Nina Scholz over 8 years@Druzion, the Internet Explorer does not have
Math.sign()
. -
Kaspar Lee over 8 years@NinaScholz Ah yes, it is also not supported in Safari and all Mobile Browsers, according to MDN
-
Kaspar Lee over 8 yearsNo, if the data types are different, it returns 0. Check the new JSFiddle
-
Léo over 8 yearsit's fixed, can you check ?
-
Léo over 8 years
nil
doesn't exist in javascript, it'snull
-
Romain 'Maz' BILLOIR almost 3 yearsAs of today and according to CanIUse.com : Math.sign is supported by almost 95% browsers. If your target clients is that guys who update their browsers, you can assume it's now safe to use it.
-
Manngo about 2 yearsFor those desperate to support Legacy Browsers:
if(!Math.sign) Math.sign=function(value) {return value?(value<0?-1:1):0};
will do for a polyfill.