JavaScript中如何将下述匹配数组合并代码的forEach替换为map方法
需求说明
现有两个均包含id属性及其他属性的数组,需要对比两个数组生成新数组,为arr1中id能和arr2匹配的对应对象添加age属性。
原有实现问题
- 采用双层forEach嵌套遍历,时间复杂度为O(n*m),数组量级较大时性能较差
- 最终只保留了id匹配成功的元素,arr1中id为2的元素会直接丢失,仅适用于只要匹配结果的场景,不符合需要完整保留arr1所有元素的通用需求
- 写法冗余,逻辑可读性不高
优化实现方案
首先将arr2转换为以id为键、age为值的Map映射,后续查找操作时间复杂度为O(1),整体复杂度降低为O(n+m),性能更高。
场景1:完整保留arr1所有元素,匹配到的加age属性,未匹配的保留原有属性
let arr1 = [{ id: 1, name: 'a' }, { id: 2, name: 'b' }, { id: 3, name: 'c' }]; let arr2 = [{ id: 1, age: 20 }, { id: 3, age: 35 }]; // 构建id到age的映射 const ageMap = new Map(arr2.map(item => [item.id, item.age])); // 遍历arr1生成新数组,不修改原数组对象 const newArr = arr1.map(item => { const matchAge = ageMap.get(item.id); return matchAge ? Object.assign({}, item, { age: matchAge }) : { ...item }; }); console.log(newArr); // 输出:[{id:1, name: 'a', age:20}, {id:2, name: 'b'}, {id:3, name: 'c', age:35}]
场景2:和原有实现逻辑一致,仅保留id匹配成功的元素
let arr1 = [{ id: 1, name: 'a' }, { id: 2, name: 'b' }, { id: 3, name: 'c' }]; let arr2 = [{ id: 1, age: 20 }, { id: 3, age: 35 }]; const ageMap = new Map(arr2.map(item => [item.id, item.age])); const newArr = arr1 .filter(item => ageMap.has(item.id)) .map(item => Object.assign({}, item, { age: ageMap.get(item.id) })); console.log(newArr); // 输出:[{id:1, name: 'a', age:20}, {id:3, name: 'c', age:35}]
内容的提问来源于stack exchange,提问作者UI_Brain
相关产品推荐
相关产品推荐

