Closed
Description
When we call indexOf/lastIndexOf on our list implementations, we let the elements in the list dictate if they are equals to the "thing" we're searching for. I find that a bit counterintuitive. I'd prefer if we always asked the thing we're searching for if it feels like it's equal to the elements like this:
class Yes { operator==(other) => true; }
var list = [ 1, 2, 3 ];
Expect.equals(0, list.indexOf(new Yes()));
Expect.equals(2, list.lastIndexOf(new Yes()));
Metadata
Metadata
Assignees
Labels
Type
Projects
Milestone
Relationships
Development
No branches or pull requests
Activity
kasperl commentedon Jun 18, 2012
Update bug description. Wooops.
Changed the title to: "Let the element we're looking for be the receiver in == calls in indexOf/lastIndexOf".
lrhn commentedon Jun 28, 2012
It's probably better that way, but mainly for performance reasons - it means that it's the same equals method that is called a lot of times, instead of potentially different ones called once each.
If the equality operator is done correctly, it should be symmetric, so it shouldn't matter which one is used. If the equality operator on your object cheats, and really just tries to match another object in some fancy way, you should search using a predicate instead (which we should make sure is also possible).
I actually slightly prefer using the existing objects' equality check in order to discourage such trickery. I.e., your example is a bad example. Positively naughty!
So I would suggest that List<T> gets
int indexOfMatch(bool predicate(T value));
which you should use instead.
DartBot commentedon Jun 30, 2012
This comment was originally written by @seaneagan
whichever one is the receiver, it should be consistent with Collection#contains (issue #1030).
Instead of List#indexOfMatch/indexOfLastMatch I would prefer Collection#find:
E find(bool predicate(E item));
DartBot commentedon Jul 1, 2012
This comment was originally written by @seaneagan
I filed Collection#find as issue #3948
lrhn commentedon Sep 18, 2012
I think we should have both List.indexOfMatch/lastIndexOfMatch and Collection.find. The collection method makes sense for all collections, but index-operations only make sense for lists.
Added this to the M2 milestone.
Added Accepted label.
lrhn commentedon Oct 24, 2012
It is consistent with Collection.contains now. We generally let the collection determine if it has something equal to the argument of contains, indexOf (and if we don't, we should fix that).
DartBot commentedon Dec 6, 2012
This comment was originally written by @seaneagan
If we had List.pairs (see issue #3948) and Iterable.find (issue #7088), then we probably wouldn't need indexOfMatch/indexOfLastMatch since then instead of:
list.indexOfMatch(test)
one could do:
list.pairs.find((pair) => test(pair.value)).key;
... which also allows one to find both the matching index and value with a single iteration of the list.
floitschG commentedon Dec 12, 2012
Removed this from the M2 milestone.
Added this to the M3 milestone.
anders-sandholm commentedon Feb 26, 2013
Removed this from the M3 milestone.
Added this to the M4 milestone.
larsbak commentedon May 28, 2013
Removed this from the M4 milestone.
Added this to the M5 milestone.
lrhn commentedon Aug 19, 2013
We are not going to change the order of the operands of ==.
I'll keep this issue open as a request for indexOfMatch/lastIndexOfMatch.
Removed Type-Defect label.
Added Type-Enhancement label.
Changed the title to: "Add predicate-parameterized search functions to List: indexOfMatch/lastIndexOfMatch".
kasperl commentedon Jun 4, 2014
Removed this from the M5 milestone.
Added this to the 1.6 milestone.
kasperl commentedon Jul 10, 2014
Removed this from the 1.6 milestone.
Added Oldschool-Milestone-1.6 label.
kasperl commentedon Aug 4, 2014
Removed Oldschool-Milestone-1.6 label.
floitschG commentedon Aug 14, 2017
Closing as dupe of #30275.