Enumerate or map through a list with index and value in Dart

There 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;
  }
}

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!


You 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

Tags:

Dart

Flutter