简体   繁体   English

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

[英]Merge two javascript maps by comparing their keys

i want to merge two Maps:我想合并两个地图:

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()

so the new Map should look like所以新的 Map 应该看起来像

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

How to achieve this?如何做到这一点?

You could iterate the maps and reduce a new map.您可以迭代地图并减少新的 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; }

Traverse newly created key-value pair array from both map and set it into the new map.从 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]);

Interesting no one suggested this solution, but this is one other method:有趣的是,没有人建议这种解决方案,但这是另一种方法:

 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);

Since the Map constructor takes any iterable, you can use a generator function that takes the maps and an optional merge strategy for values.由于Map 构造函数采用任何可迭代对象,因此您可以使用生成器 function采用映射和可选的值合并策略。 Then iterate over the keys and use the merge strategy to combine the values.然后遍历键并使用合并策略来组合值。 By default, you can just merge two objects:默认情况下,您可以只合并两个对象:

 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); }

This can be generalised for any amount of maps and the ability to handle maps with potentially different keys.这可以推广到任意数量的地图以及处理具有潜在不同键的地图的能力。 Assuming the intention is to merge only existing values, then it can be done like this:假设目的是仅合并现有值,则可以这样做:

 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