JavaScript中合并相同ID对象数组属性值的最优方案
问题描述
我们有一个包含id、id2和description属性的对象数组:
foo[0].id // "45g-332" foo[0].id2 // "45G-000332" foo[0].description // "tomatoes" foo[1].id // "45f-842" foo[1].id2 // "45F-000842" foo[1].description // "cherries" foo[2].id // "45g-332" foo[2].id2 // "45G-000332" foo[2].description // "peaches"
需要生成一个变量或对象,将相同id对应的所有description合并,可选结果有两种:
结果一:数组形式
bar[0].id // "45g-332" bar[0].id2 // "45G-000332" bar[0].description // "tomatoes; peaches" bar[1].id // "45f-842" bar[1].id2 // "45F-000842" bar[1].description // "cherries"
结果二:键值对(关联标签)形式
bar["45g-332"].description // "tomatoes; peaches" bar["45f-842"].description // "cherries" bar["45g-332"].id2 // "45G-000332"
我自己实现了一个可行方案:
let foo = []; foo[0] = []; foo[1] = []; foo[2] = []; foo[0].id = "45g-332"; foo[0].id2 = "45G-000332"; foo[0].description = "tomatoes"; foo[1].id = "45f-842"; foo[1].id2 = "45F-000842"; foo[1].description = "cherries"; foo[2].id = "45g-332"; foo[2].id2 = "45G-000332"; foo[2].description = "peaches"; let bar = []; for (let i in foo) { // 遍历源数组foo if (bar[foo[i].id]) { // 检查目标对象bar中是否已存在该id对应的项 bar[foo[i].id].description += "; " + foo[i].description; // 追加description } else { bar[foo[i].id] = []; // 创建新项 bar[foo[i].id].description = foo[i].description; }; bar[foo[i].id].id2 = foo[i].id2; // 补充id2属性 }; for (let i in bar) { console.log("id: " + i + " has: " + bar[i].description + " and id2: " + bar[i].id2); }; // 输出结果 // "id: 45g-332 has: tomatoes; peaches and id2: 45G-000332" // "id: 45f-842 has: cherries and id2: 45F-000842"
我确信存在更简洁的实现方式,请问业界标准方案是什么?
业界标准实现方案
JavaScript中处理这类分组合并需求,最常用的是Array.prototype.reduce方法,它能更简洁高效地完成分组逻辑,同时兼顾可读性。
实现键值对形式的结果
const foo = [ { id: "45g-332", id2: "45G-000332", description: "tomatoes" }, { id: "45f-842", id2: "45F-000842", description: "cherries" }, { id: "45g-332", id2: "45G-000332", description: "peaches" } ]; // 使用reduce分组合并 const bar = foo.reduce((acc, current) => { // 如果当前id已存在于累加器中,追加description if (acc[current.id]) { acc[current.id].description += "; " + current.description; } else { // 不存在则创建新对象,拷贝所有属性并初始化description acc[current.id] = { ...current }; } return acc; }, {}); // 输出验证 console.log(bar["45g-332"].description); // "tomatoes; peaches" console.log(bar["45f-842"].description); // "cherries" console.log(bar["45g-332"].id2); // "45G-000332"
实现数组形式的结果
如果需要转换成数组形式,只需在上述基础上调用Object.values():
const barArray = Object.values(bar); // 输出验证 console.log(barArray[0].id); // "45g-332" console.log(barArray[0].description); // "tomatoes; peaches" console.log(barArray[1].id); // "45f-842"
方案优势
- 简洁性:用reduce将遍历、判断、合并逻辑浓缩在一个方法中,代码更紧凑。
- 可读性:逻辑清晰,符合函数式编程的主流写法,团队协作时更容易理解。
- 扩展性:若后续需要增加其他属性的处理,只需修改回调函数内的逻辑即可。
内容的提问来源于stack exchange,提问作者Robbit
相关产品推荐
相关产品推荐

