Reputation: 111
I have a map of type Map> , I need to add values to the Set multiple times :
Fields = new Map<string, Set<string>>();
this.array1.forEach(s => this.Fields.set(`${s.id}`, Utils1.otherFields(s)));
this.array2.forEach(s => this.Fields.set(`${s.id}`, Utils2.otherFields2(s)));
now the loop does the job perfectly , but when I return the Map , it only has the last values set in it , which is in this case values from otherFields2.
what am I doing wrong ?
Upvotes: 0
Views: 6213
Reputation: 330511
JavaScript doesn't have a lot of built-in support for manipulating Map
s and Set
s, so you'll have to write this yourself. Here's a possible way to do this.
First, let's introduce the Map
utility function computeIfAbsent()
, (inspired by a Java Map
method of the same name) which takes a map and a key, and a callback function to compute a default value for that key. It behaves sort of like a map.get(key)
which is guaranteed to return a result. If the map has a value for that key, you get it. Otherwise, the callback is called to make a value, and that value is put into the map before it's returned to you:
function computeIfAbsent<K, V>(map: Map<K, V>, key: K, mappingFunction: (key: K) => V): V {
let val = map.get(key);
if (typeof val === "undefined") {
val = mappingFunction(key);
map.set(key, val);
}
return val;
}
Then we introduce the Set
utility function addAll()
, (inspired by a Java Set
method of the same name) which takes a set and a collection of values, and adds all the values from the collection into the set:
function addAll<V>(s: Set<V>, other: Iterable<V>) {
for (const o of other) s.add(o);
}
Armed with both of those, your code should be changed to something like this:
this.array1.forEach(s => addAll(
computeIfAbsent(this.Fields, `${s.id}`, () => new Set()),
Utils1.otherFields(s)
));
this.array2.forEach(s => addAll(
computeIfAbsent(this.Fields, `${s.id}`, () => new Set()),
Utils2.otherFields2(s)
));
The idea is that for each element s
in the array, you get the Set<string>
corresponding to the s.id
key in the Fields
map, or create a new empty one if it isn't there. Then, to this set you add all the values from your Utils
method. This should have the effect of merging instead of overwriting.
Okay, hope that helps; good luck!
Upvotes: 2