有没有一个简单的方法来合并ES6映射在一起(像Object.assign)?说到这里,ES6集合(比如Array.concat)呢?
当前回答
你可以使用spread语法将它们合并在一起:
const map1 = {a: 1, b: 2}
const map2 = {b: 1, c: 2, a: 5}
const mergedMap = {...a, ...b}
=> {a: 5, b: 1, c: 2}
其他回答
集:
var merged = new Set([...set1, ...set2, ...set3])
地图:
var merged = new Map([...map1, ...map2, ...map3])
注意,如果多个映射具有相同的键,则合并映射的值将是具有该键的最后一个合并映射的值。
要合并数组集合中的集合,您可以执行
var Sets = [set1, set2, set3];
var merged = new Set([].concat(...Sets.map(set => Array.from(set))));
对我来说有点神秘的是,为什么下面这些应该是等价的,但至少在巴别塔失败了:
var merged = new Set([].concat(...Sets.map(Array.from)));
被认可的答案很好,但每次都会创建一个新的集合。
如果要更改现有对象,请使用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]
不,它们没有内置操作,但你可以很容易地创建自己的操作:
Map.prototype.assign = function(...maps) {
for (const m of maps)
for (const kv of m)
this.add(...kv);
return this;
};
Set.prototype.concat = function(...sets) {
const c = this.constructor;
let res = new (c[Symbol.species] || c)();
for (const set of [this, ...sets])
for (const v of set)
res.add(v);
return res;
};
我创建了一个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>