Reputation: 2575
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
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