groupIterableBy<K, V, I> function

Map<K, V> groupIterableBy<K, V, I>(
  1. Iterable<I> iterable,
  2. MapEntry<K, V> map(
    1. I entry
    ),
  3. V merge(
    1. K key,
    2. V value1,
    3. V value2
    )
)

Groups interable entries using map to generate a MapEntry for each entry, than uses merge to group entries of the same group (key).

Implementation

Map<K, V> groupIterableBy<K, V, I>(
    Iterable<I> iterable,
    MapEntry<K, V> Function(I entry) map,
    V Function(K key, V value1, V value2) merge) {
  if (iterable.isEmpty) return <K, V>{};

  var groups = <K, V>{};

  for (var entry in iterable) {
    var e = map(entry);

    var k = e.key;

    var prev = groups[k];

    if (prev == null) {
      groups[k] = e.value;
    } else {
      var v2 = merge(k, prev, e.value);
      groups[k] = v2;
    }
  }

  return groups;
}