我有一个Map类型的地图,我需要多次向Set中添加值:
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)));
现在循环完美地完成了工作,但是当我返回Map时,它只设置了最后一个值,在这种情况下,这是otherFields2的值。
我在做什么错了?
答案 0 :(得分:1)
JavaScript对于操纵Map
和Set
并没有很多内置支持,因此您必须自己编写。这是一种可行的方法。
首先,让我们介绍Map
实用程序函数computeIfAbsent()
(受Java Map
method of the same name的启发),它需要一个映射和一个键,以及一个回调函数来计算该函数的默认值键。它的行为类似于map.get(key)
,可以保证返回结果。如果映射具有该键的值,则可以获取。否则,将调用回调函数以创建一个值,并将该值在返回给您之前放入映射中:
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;
}
然后,我们引入Set
实用程序函数addAll()
(受Java Set
method of the same name的启发),该函数接受一组值和一组值,并将该组中的所有值添加到设置:
function addAll<V>(s: Set<V>, other: Iterable<V>) {
for (const o of other) s.add(o);
}
同时使用这两种方法,您的代码应更改为以下内容:
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)
));
这个想法是,对于数组中的每个元素s
,您将获得与Set<string>
映射中的s.id
键相对应的Fields
或创建一个新的空白一个,如果不存在。然后,将Utils
方法中的所有值添加到该集合中。这应该具有合并而不是覆盖的效果。
好的,希望能有所帮助;祝你好运!