有没有一个简单的方法来合并ES6映射在一起(像Object.assign)?说到这里,ES6集合(比如Array.concat)呢?


当前回答

集:

var merged = new Set([...set1, ...set2, ...set3])

地图:

var merged = new Map([...map1, ...map2, ...map3])

注意,如果多个映射具有相同的键,则合并映射的值将是具有该键的最后一个合并映射的值。

其他回答

编辑:

I benchmarked my original solution against other solutions suggests here and found that it is very inefficient. The benchmark itself is very interesting (link) It compares 3 solutions (higher is better): @fregante (formerly called @bfred.it) solution, which adds values one by one (14,955 op/sec) @jameslk's solution, which uses a self invoking generator (5,089 op/sec) my own, which uses reduce & spread (3,434 op/sec) As you can see, @fregante's solution is definitely the winner. Performance + Immutability With that in mind, here's a slightly modified version which doesn't mutates the original set and excepts a variable number of iterables to combine as arguments: function union(...iterables) { const set = new Set(); for (const iterable of iterables) { for (const item of iterable) { set.add(item); } } return set; } Usage: const a = new Set([1, 2, 3]); const b = new Set([1, 3, 5]); const c = new Set([4, 5, 6]); union(a,b,c) // {1, 2, 3, 4, 5, 6}


原来的答案

我想建议另一种方法,使用reduce和spread运算符:

实现

function union (sets) {
  return sets.reduce((combined, list) => {
    return new Set([...combined, ...list]);
  }, new Set());
}

用法:

const a = new Set([1, 2, 3]);
const b = new Set([1, 3, 5]);
const c = new Set([4, 5, 6]);

union([a, b, c]) // {1, 2, 3, 4, 5, 6}

Tip:

我们还可以使用rest操作符来使界面更好:

function union (...sets) {
  return sets.reduce((combined, list) => {
    return new Set([...combined, ...list]);
  }, new Set());
}

现在,我们不再传递一个集合数组,而是可以传递任意数量的集合参数:

union(a, b, c) // {1, 2, 3, 4, 5, 6}

将集合转换为数组,将它们平直,最后构造函数将惟一化。

const union = (...sets) => new Set(sets.map(s => [...s]).flat());

例子

const mergedMaps = (...maps) => {
    const dataMap = new Map([])

    for (const map of maps) {
        for (const [key, value] of map) {
            dataMap.set(key, value)
        }
    }

    return dataMap
}

使用

const map = mergedMaps(new Map([[1, false]]), new Map([['foo', 'bar']]), new Map([['lat', 1241.173512]]))
Array.from(map.keys()) // [1, 'foo', 'lat']

被认可的答案很好,但每次都会创建一个新的集合。

如果要更改现有对象,请使用helper函数

在不久的将来,你可以只使用setA.union(setB)

Set

function concatSets(set, ...iterables) {
    for (const iterable of iterables) {
        for (const item of iterable) {
            set.add(item);
        }
    }
}

用法:

const setA = new Set([1, 2, 3]);
const setB = new Set([4, 5, 6]);
const setC = new Set([7, 8, 9]);
concatSets(setA, setB, setC);
// setA will have items 1, 2, 3, 4, 5, 6, 7, 8, 9

Map

function concatMaps(map, ...iterables) {
    for (const iterable of iterables) {
        for (const item of iterable) {
            map.set(...item);
        }
    }
}

用法:

const mapA = new Map().set('S', 1).set('P', 2);
const mapB = new Map().set('Q', 3).set('R', 4);
concatMaps(mapA, mapB);
// mapA will have items ['S', 1], ['P', 2], ['Q', 3], ['R', 4]

一个很好的解决方案,无论你是否有两个或更多的映射合并是将它们作为一个数组,并使用以下:

Array.prototype.merge = function () {
  return this.reduce((p, c) => Object.assign(c, p), {});
};