https://dart.dev/language/collections#control-flow-operators[`for` elements] should be preferred to https://api.dart.dev/stable/dart-core/Map/Map.fromIterable.html[`fromIterable`] when building a https://api.dart.dev/stable/dart-core/Map/Map.html[`Map`] from an https://api.dart.dev/stable/dart-core/Iterable-class.html[`Iterable`]. == Why is this an issue? While it is possible to build a `Map` from an `Iterable` using `Map.fromIterable`, writing an explicit `for` loop with `for` elements should be used instead. The main reason to prefer `for` elements is that it can be optimized by the Dart compiler for performance, depending on the iterable being visited. Moreover, `for` elements are more idiomatic and generally easier to understand than `Map.fromIterable`, which requires explicit map type upfront, as well as the input iterable and two different lambda functions as parameters. [source,dart] ---- Map.fromIterable( // Explicit Map type required inputIterable, key: (item) => ..., // Key generator value: (item) => ..., // Value generator ); ---- On the other hand, `for` elements are more flexible, look like normal `for` loops, and support better inference of the resulting `Map` type. [source,dart] ---- { for (final item in inputIterable) 'The value is $v': v // Implicit Map type inference } ---- === Exceptions The rule only applies to the `fromIterable` factory method of `Map`. It does not apply to other `fromIterable` methods, such as the one from `LinkedHashMap` in `dart:collection`. Moreover, it only applies when all the arguments of the `Map.fromIterable` call are provided. If either the `key` or the `value` parameter is omitted, the rule does not apply. [source,dart] ---- Map.fromIterable(l1, key: (item) => ...); // OK Map.fromIterable(l1, value: (item) => ...); // OK ---- The rule also does not apply when the `key` and `value` parameters are not inline function expressions, but variables defined elesewhere in the code. [source,dart] ---- final key = (item) => ...; final value = (item) => ...; Map.fromIterable(l1, key: key, value: value); ---- == How to fix it In order to replace `Map.fromIterable` with `for` elements: * replace the `Map.fromIterable` call with a `for` loop over the input iterable, that is the first argument of the call * define the body of the `for` elements as a `key: value` pair, where `key` is the body of the key generator lambda, and `value` is body of the value generator lambda === Code examples ==== Noncompliant code example [source,dart,diff-id=1,diff-type=noncompliant] ---- Map.fromIterable( [1, 2, 3], key: (v) => 'The value is $v', value: (v) => v, ); ---- ==== Compliant solution [source,dart,diff-id=1,diff-type=compliant] ---- { for (final v in [1, 2, 3]) 'The value is $v': v } ---- == Resources === Documentation * Dart Docs - https://dart.dev/tools/linter-rules/prefer_for_elements_to_map_fromIterable[Linter rule - prefer_for_elements_to_map_fromIterable] * Dart Docs - https://dart.dev/language/collections#control-flow-operators[Language - Control-flow operators] * Dart API Reference - https://api.dart.dev/stable/dart-core/Map/Map.html[Map class] * Dart API Reference - https://api.dart.dev/stable/dart-core/Iterable-class.html[Iterable class] * Dart API Reference - https://api.dart.dev/stable/dart-core/Map/Map.fromIterable.html[Map.fromIterable constructor] ifdef::env-github,rspecator-view[] ''' == Implementation Specification (visible only on this page) === Message Use 'for' elements when building maps from iterables. === Highlighting The entire `Map.fromIterable` call, including parentheses and arguments: e.g. `Map.fromIterable([1, 2, 3], key: (v) => 'The value is $v', value: (v) => v);`. endif::env-github,rspecator-view[]