如何在打字稿中为Map <string,Set <string >>添加值?

时间:2019-11-14 15:34:40

标签: typescript dictionary

我有一个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的值。

我在做什么错了?

1 个答案:

答案 0 :(得分:1)

JavaScript对于操纵MapSet并没有很多内置支持,因此您必须自己编写。这是一种可行的方法。

首先,让我们介绍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方法中的所有值添加到该集合中。这应该具有合并而不是覆盖的效果。

好的,希望能有所帮助;祝你好运!

Link to code