有没有一个简单的方法来合并ES6映射在一起(像Object.assign)?说到这里,ES6集合(比如Array.concat)呢?
当前回答
当向现有集合中添加多个元素(来自数组或另一个集合)时,调用new Set(…anArrayOrSet)没有任何意义。
我在reduce函数中使用了这个,它只是简单的愚蠢。即使你有…数组展开运算符可用,在这种情况下不应该使用它,因为它浪费处理器、内存和时间资源。
// Add any Map or Set to another
function addAll(target, source) {
if (target instanceof Map) {
Array.from(source.entries()).forEach(it => target.set(it[0], it[1]))
} else if (target instanceof Set) {
source.forEach(it => target.add(it))
}
}
演示片段
// Add any Map or Set to another function addAll(target, source) { if (target instanceof Map) { Array.from(source.entries()).forEach(it => target.set(it[0], it[1])) } else if (target instanceof Set) { source.forEach(it => target.add(it)) } } const items1 = ['a', 'b', 'c'] const items2 = ['a', 'b', 'c', 'd'] const items3 = ['d', 'e'] let set set = new Set(items1) addAll(set, items2) addAll(set, items3) console.log('adding array to set', Array.from(set)) set = new Set(items1) addAll(set, new Set(items2)) addAll(set, new Set(items3)) console.log('adding set to set', Array.from(set)) const map1 = [ ['a', 1], ['b', 2], ['c', 3] ] const map2 = [ ['a', 1], ['b', 2], ['c', 3], ['d', 4] ] const map3 = [ ['d', 4], ['e', 5] ] const map = new Map(map1) addAll(map, new Map(map2)) addAll(map, new Map(map3)) console.log('adding map to map', 'keys', Array.from(map.keys()), 'values', Array.from(map.values()))
其他回答
我已经创建了一个小片段,使用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}
我创建了一个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>
一个很好的解决方案,无论你是否有两个或更多的映射合并是将它们作为一个数组,并使用以下:
Array.prototype.merge = function () {
return this.reduce((p, c) => Object.assign(c, p), {});
};
例子
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]