You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 12:55:19