Nico Rodsevich
Nico Rodsevich

Reputation: 2575

How to unify maps in Dart?

Given any Iterable<Map> I would like to get a Map with the union of all the components of them in a Set.

e.g.:

{"foo":1,"bar":1},{"bar":2},{"bar":1,"baz":1},{"bar":2,"foo":2}

should return a

{"foo":{1,2},"bar":{1,2},"baz":{1}}

I just wrote the code, but the question is for available libraries in the SDK (or else in packages) that does this common task

Map unifyMaps(Iterable<Map> values) {
if (values.isEmpty) {
  return null;
} else if (values.length == 1) {
  return values.single;
} else {
  Map ret = {};
  values.forEach((m) {
    m.forEach((k, v) {
      if (ret[k] == null) {
        ret[k] = {v};
      } else {
        ret[k].add(v);
      }
    });
  });
  return ret;
}

}

Upvotes: 0

Views: 153

Answers (1)

Kevin Moore
Kevin Moore

Reputation: 6171

Here you go...

void main() {
  var inputs = [{"foo":1,"bar":1},{"bar":2},{"bar":1,"baz":1},{"bar":2,"foo":2}];
  print(inputs);
  print(unifyMaps(inputs));
}

Map<String, Set<T>> unifyMaps<T>(Iterable<Map<String, T>> source) {
  var result = <String, Set<T>>{};
  for (var entry in source.expand((m) => m.entries)) {
    result.putIfAbsent(entry.key, () => <T>{}).add(entry.value);
  }
  return result;
}

Or if you want to get a bit too fancy

Map<String, Set<T>> unifyMaps<T>(Iterable<Map<String, T>> source) =>
    source.expand((m) => m.entries).fold(
        <String, Set<T>>{},
        (result, entry) =>
            result..putIfAbsent(entry.key, () => <T>{}).add(entry.value));

Upvotes: 1

Related Questions