Ok, easy goof (I was boarding a plane -- that's my excuse!). But easy to
fix too.
Point is, as Peter posted, this is hard to get right if one has to write
it from scratch. Finding and downloading a standard library? Why not
make that the built-in all implementations provide?
/be
Mark S. Miller wrote:
On Sun, Apr 1, 2012 at 6:56 PM, Mark S. Miller <[email protected]
<mailto:[email protected]>> wrote:
On Sun, Apr 1, 2012 at 3:53 PM, Brendan Eich <[email protected]
<mailto:[email protected]>> wrote:
arr.sort((a, b) => (a.prop< b.prop) ?-1 : (a.prop> b.prop)
? 1 : 0);
and if you weed out NaN to avoid the comparison function
returning NaN, while taking advantage of the fact that the
return value's sign is all that matters, not exact {-1, 0, 1}
membership, then it's not much worse:
arr.sort((a, b) => { let t = a.prop - b.prop; return (t !==
t) ? 0 : t; });
Quoting from <http://es5.github.com/#x15.4.4.11>, the requirements
on the comparefn are:
A function /comparefn/ is a consistent comparison function
for a set of values /S/ if all of the requirements below
are met for all values /a/, /b/, and /c/ (possibly the
same value) in the set /S/: The notation /a/ <_CF
/b/ means /comparefn/(/a/,/b/) < 0; /a/ =_CF /b/ means
/comparefn/(/a/,/b/) = 0 (of either sign); and/a/ >_CF
/b/ means /comparefn/(/a/,/b/) > 0.
Calling /comparefn/(/a/,/b/) always returns the same value
/v/ when given a specific pair of values /a/and /b/ as its
two arguments. Furthermore, Type
<http://es5.github.com/#Type>(/v/) is Number, and /v/ is
not NaN. Note that this implies that exactly one of /a/
<_CF /b/, /a/ =_CF /b/, and /a/ >_CF /b/ will be true for
a given pair of /a/ and /b/.
Calling /comparefn/(/a/,/b/) does not modify the
*this* object.
/a/ =_CF /a/ (reflexivity)
If /a/ =_CF /b/, then /b/ =_CF /a/ (symmetry)
If /a/ =_CF /b/ and /b/ =_CF /c/, then /a/ =_CF
/c/ (transitivity of =_CF )
If /a/ <_CF /b/ and /b/ <_CF /c/, then /a/ <_CF
/c/ (transitivity of <_CF )
If /a/ >_CF /b/ and /b/ >_CF /c/, then /a/ >_CF
/c/ (transitivity of >_CF )
*NOTE*
The above conditions are necessary and sufficient to
ensure that /comparefn/ divides the set/S/ into
equivalence classes and that these equivalence classes are
totally ordered.
If sort is called with a comparefn which violates this constraint,
according to normative text
If /comparefn/ is not *undefined* and is not a consistent
comparison function for the elements of this array
<http://es5.github.com/#array-element> (see below), the
behaviour of |*sort*| is implementation-defined.
a conforming implementation may kill the user, lose memory safety,
or launch the nukes.
Since in this note we're not concerned about new syntax but rather
the notion of "implementation-defined", let's rewrite Brendan's
two sort functions in ES5:
function c1(a, b) {
return a < b ? -1 : a > b ? 1 : 0;
}
function c2(a, b) {
var t = a - b;
return t !== t ? 0 : 1;
Oops, typo. The "1" immediately above should be "t". But this doesn't
affect the point.
}
Both of these violate transitivity of =_CF
c1(3,NaN);
0
c1(NaN,4);
0
c1(3,4);
-1
c2(3,NaN)
0
c2(NaN,4)
0
c2(3,4)
1
Fortunately, I have not tried passing either of these to sort, and
so have lived to tell the tale.
Let's kill "implementation-defined" rather than our users.
I'm assuming you don't need to sort -0< 0 (which evaluates to
false in JS).
Another observation: this last version is the only one that
avoids multiple implicit conversions via toString or valueOf
of an object operand, if one or both of a and b is an object
and the first condition (a.prop< b.prop) evaluates to false.
This means the only portable form is the last version.
Yeah, it's a pain to write every time and people will mess up
the NaN corner case. A standard built-in would be good. But
why use a string parameter key instead of just a built-in
function?
/be
_______________________________________________
es-discuss mailing list
[email protected] <mailto:[email protected]>
https://mail.mozilla.org/listinfo/es-discuss
--
Cheers,
--MarkM
--
Cheers,
--MarkM
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss