-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
respect iterator return value of Infinity/-Infinity in _.min/_.max #1606
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
I'm not a fan of mucking with the comparison logic with |
I don't see how the spec relates to this specific issue, @jdalton, since Math.max does not accept an iterator. It's awkward to state in the documentation: Iterators should not return Infinity/-Infinity. Use Number.MAX_VALUE/Number.MIN_VALUE instead. |
It's the result of the iterator that is the important thing. The result is what's used to resolve values to compare. The comparison is what aligns with the spec.
Naw. If you want to get specific you can say that it compares values according to the abstract comparison algorithm, which is just a fancy way to say |
@jdalton, are you suggesting that this is correct behaviour? > _.max([{name: 'Alice', score: -Infinity}, {name: 'Bob', score: -Infinity}], _.property('score'))
-Infinity I would expect to get back the Alice object or the Bob object, not -Infinity. |
Ok, I could see that, though I wouldn't want to change the |
I not fussed either way, so I'll go ahead and update the PR to avoid changing the operators. |
Thanks very much for your feedback, @jdalton. The PR is in a better state as a result. It no longer uses |
var a = {x: -Infinity}; | ||
var b = {x: -Infinity}; | ||
var iterator = function(o){ return o.x; }; | ||
equal(_.max([a, b], iterator), a, 'Respects iterator return value of -Infinity'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test ensures that the first element in the list is returned.
Are you happy with this PR as it currently stands, @jdalton? |
Yap, rocks! |
respect iterator return value of Infinity/-Infinity in _.min/_.max
A colleague and I were just bitten by a bug in this code:
We were surprised to discover that
bestMatch
would in some cases be -Infinity rather than an object. This results from Underscore performing>
comparisons against an initial max of -Infinity. Since -Infinity is not greater than -Infinity, the initial value is erroneously returned if the iterator returns -Infinity for each element in a nonempty collection.I've implemented the least invasive fix, which is to use
>=
and<=
in place of>
and<
. Note that this does change undocumented behaviour not covered by the test suite: the last min/max element will be returned rather than the first. Consider a slightly modified version of the example from the documentation:If we wish to preserve this undocumented behaviour, I'll add appropriate test cases and adjust the implementations of _.min and _.max accordingly. This may simply involve enumerating the given collection in reverse order.