-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Addition to stdlib proposal: Iterable.enumerate #32467
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
Comments
One of the many use-cases for this addition is as follows. children: photos.enumerate((index, photo) {
return new Positioned(
left: 6.0 * index,
height: 60.0,
child: new Image.file(new File(photo), fit: BoxFit.cover),
);
}).toList(), |
It would be awesome to have the index w/in an iterating function of a list and be able to avoid dangerous methods like using |
This reminds me of What about something like: class ListEntry<E> {
E element;
int index;
}
class Iterable<E> {
...
Iterable<ListEntry<E>> get entries;
} Then your example is: children: photos.entries.map((entry) {
return new Positioned(
left: 6.0 * entry.index,
height: 60.0,
child: new Image.file(new File(entry.element), fit: BoxFit.cover),
);
}).toList(); |
Oh that is interesting. I did not know I don't know if that requirement is a hurdle in practice. |
@natebosch excellent work around until this gets added, but still I think it'd be simpler to have this functionality |
Thinking about this further I don't think Namely the cases where you do not have the entire collection up-front (networking, etc). Nonetheless it is useable for the presented situation. |
Is the use case for this so compelling that you couldn't just use a for loop instead? They're just about the same length and complexity. var children = <Widget>[];
for (var i = 0; i < photos.length; i++) {
children.add(new Positioned(
left: 6.0 * i,
height: 60.0,
child: new Image.file(new File(photos[i]), fit: BoxFit.cover),
));
}
There are so many different operations we do on Lists which could be expressed as their own Iterator method. It seems like it would be more sustainable long term to be less opinionated, and spend the effort on something like extension methods. Then you could have libraries like quiver define their own Iterator methods. |
There are many things you can do with lazy combinator chains that don't work out to as neat of a solution as a good old-fashioned for loop. The example I provided was intentionally small and simple. Being opinionated about the stdlib provided by your language is not a bad thing nor is it mutually exclusive with extension methods. Of course time isn't infinite so you must pick your battles but is the addition of extension methods on the roadmap for Dart currently? The same argument could have been made for |
The reality is adding more members on a core collection like this without extension methods is extremely time consuming and wouldn't have large enough value to justify it. I'd recommend using a top-level method for the time being: Iterable<E> mapEnumerated<T>(Iterable<T> iterable, E Function<E>(T, int) fn) sync* {
var index = 0;
for (final item in iterable) {
yield fn(item, index++);
}
} Example use: children: mapEnumerated(photos, (element, index) {
return new Positioned(
left: 6.0 * index,
height: 60.0,
child: new Image.file(new File(element), fit: BoxFit.cover),
);
}).toList(); Compared to |
How about adding zero new methods and simply taking advantage of optional parameters? The // currently... (E e)
Iterable<T> map<T>(T f(E e)) => new MappedIterable<E, T>(this, f);
// proposed... (E e, [int index])
Iterable<T> map<T>(T f(E e, [int index])) => new MappedIterable<E, T>(this, f);
// added `index` as optional ^ positional argument to callback Since the index is optional, it should limit breaking changes with exiting code. |
It's breaking for any class which |
There's no way for Dart to understand that params (E e) is a subset of (E e, [int index)) ? Or at least that it satisfies the former's condition. |
Ah I misread the proposal. The subclass wouldn't be a static error in this case, but existing callers would have a static error since they must provide a callback with an optional argument. There is no way to express with the Dart type system "Either a function that takes 1 argument of type E, or a function that takes an E and an int". You have to fall back to You can play around with the analyzer to see these errors in practice. |
Uh oh!
There was an error while loading. Please reload this page.
The iterator returned yields pairs
(i, e)
, wherei
is the current index of iteration ande
is the element returned by the iterator.The
enumerate
adaptor is exactly the same asmap
but with the added index parameter.Here is one such implementation:
https://github.com/google/quiver-dart/blob/master/lib/src/iterables/enumerate.dart
The text was updated successfully, but these errors were encountered: