Conversation
Member
Author
|
Hmm, I just realized that this won’t work because the array could only have non-orderable values in it, and thus the last comparison could return NaN even if the search value is orderable. For example, this now fails: const values = [null, undefined, NaN];
assert.strictEqual(bisectLeft(values, 1), 0);
assert.strictEqual(bisectLeft(values, 2), 0);If the comparator is specified as a function that takes (object, value), there’s no way for us to test just an object for orderability (because we can’t construct a synthetic value to test against), just like we can’t test just a value for orderability (because we can’t construct a synthetic object to test against). So… I think we might be stuck here, although we could special case specific comparators that we know to be symmetric. 🤔 |
3888d56 to
6be94fe
Compare
Fil
approved these changes
Apr 11, 2022
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #249. Previously #227.
If the bisector was given an asymmetric comparator that takes (object, value) as arguments, then the test for whether the search value is orderable was failing because it would pass the comparator (value, value), which the comparator likely did not expect, and thus would typically return NaN or undefined.
So instead, we now perform the bisection without first testing for orderability, but if the final comparison at the end of bisection returns NaN, we know that the search value was not orderable. In the case that the search value is not orderable, this is obviously slower since we still perform the bisection, but we don’t need to optimize for this case and it’s better to be correct and backwards compatible.We can’t do this; see comment below.So instead, we now limit the search value orderability test to when the bisector uses an accessor or a known symmetric comparator (specifically d3.ascending and d3.descending, which are used by d3.bisectLeft et al.). It’s a bummer that this means we can’t enforce that non-orderable values go to the end in the general case, but I don’t think it’s possible given the constraints, at least not without breaking backwards compatibility and requiring the use of symmetric comparators (or accessors).