基于userid合并数组对象并保留各自所有属性的实现问题
问题原因
你现有代码的问题主要有两个:
- 仅遍历了主数组
a1的元素,没有将第二个数组a2中未匹配到对应userid的新对象追加到结果中,所以会丢失新的userid对应的条目 - 字段名匹配错误,你的示例中用户ID的字段名为
userid,但代码里写的是user_id,拼写不一致会导致匹配失效
修复方案
方案1:基于原有逻辑修改
如果想保留你原本的实现思路,可以补充新对象追加的逻辑:
const mergeById = (a1, a2) => { // 合并主数组已有元素的属性 const mergedExisting = a1.map(itm => { const matchedItem = a2.find(item => item.userid === itm.userid) return matchedItem ? {...itm, ...matchedItem} : itm }) // 筛选出a2中新增的、主数组没有的对象 const newItems = a2.filter(item => !a1.some(exist => exist.userid === item.userid)) // 合并两部分结果返回 return [...mergedExisting, ...newItems] }
调用时可以直接用reduce批量处理所有迭代数组:
// 把所有待合并的迭代数组放在一个数组里 const allIterations = [iteration1, iteration2, iteration3] // 从空数组开始迭代合并得到主数组 const mainArr = allIterations.reduce((prevArr, currArr) => mergeById(prevArr, currArr), [])
方案2:Map索引优化(推荐,大数组下性能更高)
如果待合并的数组元素较多,用find/some每次遍历的时间复杂度较高,可以用Map做索引把整体复杂度降到O(n):
const mergeArraysById = (arrList, idKey = 'userid') => { const idMap = new Map() // 遍历所有数组的所有元素 arrList.forEach(arr => { arr.forEach(item => { const id = item[idKey] if (idMap.has(id)) { // 已存在同ID的对象,合并属性,后出现的属性会覆盖先出现的 idMap.set(id, {...idMap.get(id), ...item}) } else { // 不存在同ID的对象,直接存入 idMap.set(id, {...item}) } }) }) // 将Map的值转成数组返回就是最终结果 return Array.from(idMap.values()) } // 调用示例 const mainArr = mergeArraysById([iteration1, iteration2, iteration3])
内容的提问来源于stack exchange,提问作者jufg
相关产品推荐
相关产品推荐

