In dart there any equivalent to the common:
enumerate(List) -> Iterator((index, value) => f) or List.enumerate() -> Iterator((index, value) => f) or List.map() -> Iterator((index, value) => f) It seems that this is the easiest way but it still seems strange that this functionality wouldn't exist.
Iterable<int>.generate(list.length).forEach( (index) => { newList.add(list[index], index) }); 514 Answers
There is a asMap method which converts the list to a map where the keys are the index and values are the element at index. Please take a look at the docs here.
Example:
List _sample = ['a','b','c']; _sample.asMap().forEach((index, value) => f); Hope this helps!
6You can use the mapIndexed or forEachIndexed extension methods from the collection package. Note that unlike javascript's array.map() or C#'s IEnumerable.Select(), the index is the first argument, not the second argument of the callback:
import 'package:collection/collection.dart'; void main() { final inputs = ['a', 'b', 'c', 'd', 'e', 'f']; final indexes = inputs.mapIndexed((index, element) => index).toList(); inputs.forEachIndexed((index, element) { print('index: $index, element: $element'); }); print(indexes); } Live Demo
Old answer
Starting with Dart 2.7, you can use extension methods to extend the functionalities of Iterable instead of having to write helper functions:
extension ExtendedIterable<E> on Iterable<E> { /// Like Iterable<T>.map but the callback has index as second argument Iterable<T> mapIndexed<T>(T Function(E e, int i) f) { var i = 0; return map((e) => f(e, i++)); } void forEachIndexed(void Function(E e, int i) f) { var i = 0; forEach((e) => f(e, i++)); } } Usage:
final inputs = ['a', 'b', 'c', 'd', 'e', 'f']; final results = inputs .mapIndexed((e, i) => 'item: $e, index: $i') .toList() .join('\n'); print(results); // item: a, index: 0 // item: b, index: 1 // item: c, index: 2 // item: d, index: 3 // item: e, index: 4 // item: f, index: 5 inputs.forEachIndexed((e, i) => print('item: $e, index: $i')); // item: a, index: 0 // item: b, index: 1 // item: c, index: 2 // item: d, index: 3 // item: e, index: 4 // item: f, index: 5 Live Demo
10There is no built-in function to get the iteration index.
If like me you don't like the idea to build a Map (the data structure) just for a simple index, what you probably want is a map (the function) which gives you the index. Let's call it mapIndexed (like in Kotlin):
children: mapIndexed( list, (index, item) => Text("event_$index") ).toList(); The implementation of mapIndexed is simple:
Iterable<E> mapIndexed<E, T>( Iterable<T> items, E Function(int index, T item) f) sync* { var index = 0; for (final item in items) { yield f(index, item); index = index + 1; } } 6Building on @Hemanth Raj answer.
To convert it back you could do
List<String> _sample = ['a', 'b', 'c']; _sample.asMap().values.toList(); //returns ['a', 'b', 'c']; Or if you needed the index for a mapping function you could do this:
_sample .asMap() .map((index, str) => MapEntry(index, str + index.toString())) .values .toList(); // returns ['a0', 'b1', 'c2'] 0I initially thought ['one', 'two', 'three'].asMap().forEach((index, value) { ... }); would be really inefficient because it looks like it is converting the list to a map. Actually it isn't - the documentation says it creates an immutable view of the list. I double checked with the dart2js of this code:
void main() { final foo = ['one', 'two', 'three']; foo.asMap().forEach((idx, val) { print('$idx: $val'); }); } It generates lot of code! But the gist is this:
main: function() { var foo = H.setRuntimeTypeInfo(["one", "two", "three"], ...); new H.ListMapView(foo, ...).forEach$1(0, new F.main_closure()); }, H.ListMapView.prototype = { forEach$1: function(_, f) { var t1, $length, t2, i; ... t1 = this._values; $length = t1.length; for (t2 = $length, i = 0; i < $length; ++i) { if (i >= t2) return H.ioore(t1, i); f.call$2(i, t1[i]); t2 = t1.length; if ($length !== t2) throw H.wrapException(P.ConcurrentModificationError$(t1)); } }, ... }, F.main_closure.prototype = { call$2: function(idx, val) { ... H.printString("" + idx + ": " + H.S(val)); }, $signature: 1 }; So it is smart enough to do the efficient thing! Pretty clever.
Of course you can also just use a normal for loop:
for (var index = 0; index < values.length; ++index) { final value = values[index]; 1Use asMap to convert List to map first. The index of element is the key. The element becomes value. Use entries to map the key and value to anything you want.
List rawList = ["a", "b", "c"]; List<String> argList = rawList.asMap().entries.map((e) => '${e.key}:${e.value}').toList(); print(argList); Output:
[0:a, 1:b, 2:c] 1Lukas Renggli's more package includes many useful tools including 'indexed' which does exactly what you want. From the docs:
indexed(['a', 'b'], offset: 1) .map((each) => '${each.index}: ${each.value}') .join(', '); (You can ignore the offset argument unless you have a Smalltalk background :-).
You can use the mapIndexed extension from the collections package:
import 'package:collection/collection.dart'; void main() { final nums = [1, 2, 3]; final strs = nums.mapIndexed((index, element) => index.toString() + '_' + element.toString()).toList(); print(strs); // [0_1, 1_2, 2_3] } 6use -> mapIndexed(index, Element) Function
to map each element and its index to a new value.
import 'package:collection/collection.dart'; and use the map index as follows
(List).mapIndexed<Widget>( (mapIndex, mapElement) => Positioned( left: mapIndex.toDouble() * 5, child: Card( color: Colors.blue, child: Image.network( '${mapElement.ImageURL}', height: 80, width: 80)))) For convenience you can use this extension method.
extension CollectionUtil<T> on Iterable<T> { Iterable<E> mapIndexed<E, T>(E Function(int index, T item) transform) sync* { var index = 0; for (final item in this) { yield transform(index, item as T); index++; } } } 0You can use Iterable.generate factory. The following code would map an Iterable using indexes and values.
extension IterableMapIndex<T> on Iterable<T> { Iterable<E> mapIndexed<E>(E f(int index, T t)) { return Iterable.generate(this.length, (index)=>f(index, elementAt(index))); } } 0Using dart collection package you can access various list extensions
one is mapIndexed:
Iterable<R> mapIndexed<R>(R Function(int, E) convert) list of all iterable extensions
1You can create another variable to get index.
int index = 0; array?.forEach((element) { // your code is here index++; // you should add this at end of the for loop }); package:quiver includes an enumerate function that is similar to Python's enumerate function.
(Note that although package:quiver isn't from the Dart team, it is owned and maintained by Google, and many of its contributors are members of Google's Dart and Flutter teams.)