繁体   English   中英

通过比较它们的键来合并两个 javascript 映射

[英]Merge two javascript maps by comparing their keys

我想合并两个地图:

const map1 = new Map([
  [1, {title: 't1', name: 'nam1'}],
  [2, {title: 't2', name: 'nam2'}]
])



const map2 = new Map([
  [1, {value: 'v1', progress: 20}],
  [2, {value: 'v2', progress: 100}]
])



const commonMap = new Map()

所以新的 Map 应该看起来像

const commonMap = new Map([
  [1, {title: 't1', name: 'nam1', value: 'v1', progress: 20}],
  [2, {title: 't2', name: 'nam2', value: 'v2', progress: 100}]
])

如何做到这一点?

您可以迭代地图并减少新的 map。

 const map1 = new Map([[1, { title: 't1', name: 'nam1' }], [2, { title: 't2', name: 'nam2' }]]), map2 = new Map([[1, { value: 'v1', progress: 20 }], [2, { value: 'v2', progress: 100 }]]), mergedMap = [...map1, ...map2].reduce((m, [k, v]) => m.set(k, {...m.get(k), ... v }), new Map); console.log([...mergedMap]);
 .as-console-wrapper { max-height: 100%;important: top; 0; }

从 map 中遍历新创建key-value对数组,并将其设置为新的 map。

 const map1 = new Map([ [1, { title: 't1', name: 'nam1' }], [2, { title: 't2', name: 'nam2' }], ]); const map2 = new Map([ [1, { value: 'v1', progress: 20 }], [2, { value: 'v2', progress: 100 }], ]); const commonMap = new Map(); [...map1, ...map2].forEach(([x, y]) => commonMap.set(x, commonMap.has(x)? {...commonMap.get(x), ...y }: {...y }) ); console.log([...commonMap]);

有趣的是,没有人建议这种解决方案,但这是另一种方法:

 const map1 = new Map([ [1, {title: 't1', name: 'nam1'}], [2, {title: 't2', name: 'nam2'}] ]); const map2 = new Map([ [1, {value: 'v1', progress: 20}], [2, {value: 'v2', progress: 100}] ]) const commonMap = new Map(map1); map2.forEach((obj, k) => commonMap.set(k, {...obj, ...commonMap.get(k)})); console.log(...commonMap);

由于Map 构造函数采用任何可迭代对象,因此您可以使用生成器 function采用映射和可选的值合并策略。 然后遍历键并使用合并策略来组合值。 默认情况下,您可以只合并两个对象:

 const defaultMerge = (...xs) => Object.assign({}, ...xs); function* mapMerge(map1, map2, mergeFn = defaultMerge) { for (const [key, value1] of map1.entries()) { const value2 = map2.get(key); yield [key, mergeFn(value1, value2)]; } } const map1 = new Map([ [1, {title: 't1', name: 'nam1'}], [2, {title: 't2', name: 'nam2'}] ]) const map2 = new Map([ [1, {value: 'v1', progress: 20}], [2, {value: 'v2', progress: 100}] ]) const commonMap = new Map(mapMerge(map1, map2)); //display for StackSnippets for(const [key, value] of commonMap.entries()) { console.log(key, "->", value); } console.log("--- custom merge ---"); const customMergecommonMap = new Map(mapMerge( map1, map2, (a, b) => ({title: a.title, value: b.value}) )); //display for StackSnippets for(const [key, value] of customMergecommonMap.entries()) { console.log(key, "->", value); }

这可以推广到任意数量的地图以及处理具有潜在不同键的地图的能力。 假设目的是仅合并现有值,则可以这样做:

 const defaultMerge = (...xs) => Object.assign({}, ...xs); function* mapMerge(...maps) { let mergeFn = defaultMerge; if (typeof maps[maps.length - 1] === "function") { //if a merge function was passed mergeFn = maps.pop(); } //collect all keys from all maps in case of differences const allKeys = new Set( maps.flatMap(m => Array.from(m.keys())) ); for (const key of allKeys) { const values = maps.filter(m => m.has(key)) //only maps with this key.map(m => m.get(key)); //get the value yield [key, mergeFn(...values)]; } } const map1 = new Map([ [1, {title: 't1', name: 'nam1'}], [2, {title: 't2', name: 'nam2'}] ]) const map2 = new Map([ [1, {value: 'v1', progress: 20}], [2, {value: 'v2', progress: 100}] ]) const commonMap = new Map(mapMerge(map1, map2)); //display for StackSnippets for(const [key, value] of commonMap.entries()) { console.log(key, "->", value); } console.log("--- custom merge ---"); const customMergecommonMap = new Map(mapMerge( map1, map2, (a, b) => ({title: a.title, value: b.value}) )); //display for StackSnippets for(const [key, value] of customMergecommonMap.entries()) { console.log(key, "->", value); }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM