如何通过ID和Name合并2-3个JavaScript对象数组为一个?
合并多组客户端数据数组(支持任意数量输入)
这场景我之前做项目时碰到过,核心就是按唯一标识(这里是Client ID)合并对象属性,而且得支持任意数量的输入数组——毕竟有时候只需要合2个,有时候要合3个,写个通用函数就不用重复造轮子了。
思路拆解
- 用
Map来建立Client ID和合并后对象的映射,查找和更新效率比普通对象更高; - 遍历所有传入的数组,把每个对象的属性合并到对应ID的条目里;
- 最后把
Map的值转成数组,就是我们要的结果。
通用实现代码
function mergeByClientId(...arrays) { const clientMap = new Map(); // 遍历所有输入数组,跳过空数组/无意义的输入 arrays.forEach(arr => { if (!arr?.length) return; arr.forEach(client => { const clientId = client["Client ID"]; // 已有条目则合并新属性,无条目则直接存入 clientMap.set(clientId, { ...clientMap.get(clientId) || {}, ...client }); }); }); // 把Map中的值转换为数组返回 return Array.from(clientMap.values()); }
不同场景的使用示例
示例1:合并arr1和arr2
const arr1 = [ { "Client ID":"1", "Client Name":"ABC", D1:"some data", D2:"more data"}, { "Client ID":"2", "Client Name":"DEF", D1:"some data", D2:"more data"}, { "Client ID":"3", "Client Name":"GHI", D1:"some data", D2:"more data"} ]; const arr2 = [ { "Client ID":"1", "Client Name":"ABC", D3:"and more data", D4:"more more data"}, { "Client ID":"2", "Client Name":"DEF", D3:"and more data", D4:"more more data"}, { "Client ID":"3", "Client Name":"GHI", D3:"and more data", D4:"more more data"} ]; const mergedArr1_2 = mergeByClientId(arr1, arr2); console.log(mergedArr1_2); // 每个对象会包含:Client ID、Client Name、D1、D2、D3、D4
示例2:合并三个数组arr1、arr2、arr3
const arr3 = [ { "Client ID":"1", "Client Name":"ABC", D5:"other data", D6:"extra Data"}, { "Client ID":"2", "Client Name":"DEF", D5:"other data", D6:"extra Data"}, { "Client ID":"3", "Client Name":"GHI", D5:"other data", D6:"extra Data"} ]; const mergedAll = mergeByClientId(arr1, arr2, arr3); console.log(mergedAll); // 每个对象会包含所有D1-D6的属性
示例3:只合并arr2和arr3
const mergedArr2_3 = mergeByClientId(arr2, arr3); console.log(mergedArr2_3); // 每个对象包含:Client ID、Client Name、D3、D4、D5、D6
额外说明
- 如果不同数组里出现同名属性冲突(比如某个数组的
Client Name和另一个不一致),后面传入的数组会覆盖前面的属性值。如果需要自定义冲突处理逻辑,可以在合并时加判断,比如保留第一个出现的Client Name:clientMap.set(clientId, { ...clientMap.get(clientId) || {}, // 保留首次出现的Client Name,不被后续覆盖 "Client Name": clientMap.get(clientId)?.["Client Name"] || client["Client Name"], // 合并其他属性 ...Object.fromEntries(Object.entries(client).filter(([key]) => key !== "Client Name")) }); - 函数里加了
if (!arr?.length) return的判断,就算传入空数组或者undefined也不会报错,容错性更好。
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

