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


当前回答

有几种方法可以做到。你可以使用地图。合并功能:

let mergedMap = map1.merge(map2);

注意:如果任何Map的键是相同的,将使用最后一个要合并的Map中的重复键的值。

更多信息请点击这里:https://untangled.io/immutable-js-6-ways-to-merge-maps-with-full-live-examples/#:~:text=merge(),merged%20in%20will%20be%20used。

其他回答

我创建了一个helper方法来合并映射,并以所需的任何成对方式处理重复键的值:

const mergeMaps = (map1, map2, combineValuesOfDuplicateKeys) => {
  const mapCopy1 = new Map(map1);
  const mapCopy2 = new Map(map2);

  mapCopy1.forEach((value, key) => {
    if (!mapCopy2.has(key)) {
      mapCopy2.set(key, value);
    } else {
      const newValue = combineValuesOfDuplicateKeys
        ? combineValuesOfDuplicateKeys(value, mapCopy2.get(key))
        : mapCopy2.get(key);
      mapCopy2.set(key, newValue);
      mapCopy1.delete(key);
    }
  });

  return new Map([...mapCopy1, ...mapCopy2]);
};

const mergeMaps = (map1, map2, combineValuesOfDuplicateKeys) => { const mapCopy1 = new Map(map1); const mapCopy2 = new Map(map2); mapCopy1.forEach((value, key) => { if (!mapCopy2.has(key)) { mapCopy2.set(key, value); } else { const newValue = combineValuesOfDuplicateKeys ? combineValuesOfDuplicateKeys(value, mapCopy2.get(key)) : mapCopy2.get(key); mapCopy2.set(key, newValue); mapCopy1.delete(key); } }); return new Map([...mapCopy1, ...mapCopy2]); }; const map1 = new Map([ ["key1", 1], ["key2", 2] ]); const map2 = new Map([ ["key2", 3], ["key4", 4] ]); const show = (object) => { return JSON.stringify(Array.from(object), null, 2) } document.getElementById("app").innerHTML = ` <h1>Maps are awesome!</h1> <div>map1 = ${show(map1)}</div> <div>map2 = ${show(map2)}</div><br> <div>Set value of last duplicate key:<br>merged map = ${show(mergeMaps(map1, map2))}</div><br> <div>Set value of pair-wise summated duplicate keys:<br>merged map = ${show(mergeMaps(map1, map2, (value1, value2) => value1 + value2))}</div><br> <div>Set value of pair-wise difference of duplicate keys:<br>merged map = ${show(mergeMaps(map1, map2, (value1, value2) => value1 - value2))}</div><br> <div>Set value of pair-wise multiplication of duplicate keys:<br>merged map = ${show(mergeMaps(map1, map2, (value1, value2) => value1 * value2))}</div><br> <div>Set value of pair-wise quotient of duplicate keys:<br>merged map = ${show(mergeMaps(map1, map2, (value1, value2) => value1 / value2))}</div><br> <div>Set value of pair-wise power of duplicate keys:<br>merged map = ${show(mergeMaps(map1, map2, (value1, value2) => Math.pow(value1, value2)))}</div><br> `; <!DOCTYPE html> <html> <head> <title>Parcel Sandbox</title> <meta charset="UTF-8" /> </head> <body> <div id="app"></div> <script src="src/index.js"> </script> </body> </html>

集:

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

地图:

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

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

我已经创建了一个小片段,使用ES6中的一个函数合并任意数量的set。你可以改变“设置”为“地图”,让它与地图一起工作。

const mergeSets = (...args) => {
    return new Set(args.reduce((acc, current) => {
        return [...acc, ...current];
    }, []));
};

const foo = new Set([1, 2, 3]);
const bar = new Set([1, 3, 4, 5]);

mergeSets(foo, bar); // Set(5) {1, 2, 3, 4, 5}
mergeSets(foo, bar, new Set([6])); // Set(6) {1, 2, 3, 4, 5, 6}

编辑:

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}

以下是我使用生成器的解决方案:

地图:

let map1 = new Map(), map2 = new Map();

map1.set('a', 'foo');
map1.set('b', 'bar');
map2.set('b', 'baz');
map2.set('c', 'bazz');

let map3 = new Map(function*() { yield* map1; yield* map2; }());

console.log(Array.from(map3)); // Result: [ [ 'a', 'foo' ], [ 'b', 'baz' ], [ 'c', 'bazz' ] ]

集:

let set1 = new Set(['foo', 'bar']), set2 = new Set(['bar', 'baz']);

let set3 = new Set(function*() { yield* set1; yield* set2; }());

console.log(Array.from(set3)); // Result: [ 'foo', 'bar', 'baz' ]