【问题标题】:Merge Array of Objects by Same Key-Value按相同键值合并对象数组
【发布时间】:2018-08-31 18:29:35
【问题描述】:

我有一个这样的对象数组:

[
  {
    "name": "Blah",
    "description": "This is a description"
  },
  {
    "name": "Foo",
    "description": "This is a description"
  },
  {
    "name": "Bar",
    "description": "This is a description"
  },
  {
    "name": "Blah",
    "description": "This is a description"
  },
  {
    "name": "Test",
    "description": "This is a description"
  }
]

我想运行某种函数以description1 + "\n" + description2 模式组合具有相同名称的对象,所以最终结果是:

[
  {
    "name": "Foo",
    "description": "This is a description"
  },
  {
    "name": "Bar",
    "description": "This is a description"
  },
  {
    "name": "Blah",
    "description": "This is a description\nThis is a description"
  },
  {
    "name": "Test",
    "description": "This is a description"
  }
]

不需要保留数组的顺序。任何帮助,将不胜感激。谢谢!

【问题讨论】:

  • 你尝试了什么?
  • 搜索和研究,检查。不存在类似的问题。用一个中间句子总结问题,加上前后两个格式正确的例子。没有拼写、语法或标点错误。标题总结了问题,没有太多细节。引入问题,检查。帮助他人重现,检查。添加了相关标签,检查。校对,检查。回复答案,检查。唯一缺少的代码是我没有的解决方案。我会继续努力改进我的提问方式,谢谢。
  • @xd1936 您收到了我和 Robidu 的回复,因为您的问题显示 0 努力,0 研究 - 它只是寻求帮助。当您完成研究并尝试了一些事情后,将它们包括在内!你会得到更好的回应

标签: javascript arrays json for-loop javascript-objects


【解决方案1】:

您可以简单地使用Array.reduce() 创建地图,按名称分组,地图上的Object.values() 将提供您想要的结果:

let arr = [ { "name": "Blah", "description": "This is a description" }, { "name": "Foo", "description": "This is a description" }, { "name": "Bar", "description": "This is a description" }, { "name": "Blah", "description": "This is a description" }, { "name": "Test", "description": "This is a description" } ];
let result = Object.values(arr.reduce((a, {name,description})=>{
  if(a[name])
    a[name].description += "\n" + description;
   else
    a[name] = Object.assign({},{name,description});
   return a;
},{}));
console.log(result);

【讨论】:

  • 太棒了!感谢您的回复。由于Object.assign(),与 EMCAScript 2015 及更高版本配合使用非常好。
【解决方案2】:

您可以使用查找对象来查找重复项:

 const result = [], hash = {};
 for(const {name, description} of input) {
    if(hash[name]) {
      hash[name].description += "\n" + description;
    } else {
      result.push(hash[name] = { name, description });
   }
 }

【讨论】:

  • 有趣。我不知道您可以以这种身份进行for...of。非常聪明!谢谢!
【解决方案3】:

您可以使用 reduce 和 findIndex 来检查新数组是否有任何名称匹配的对象。如果是这样,请更新描述

let orgArray = [{
    "name": "Blah",
    "description": "This is a description"
  },
  {
    "name": "Foo",
    "description": "This is a description"
  },
  {
    "name": "Bar",
    "description": "This is a description"
  },
  {
    "name": "Blah",
    "description": "This is a description"
  },
  {
    "name": "Test",
    "description": "This is a description"
  }
]

let newArray = orgArray.reduce(function(acc, curr) {
  let findIndexs = acc.findIndex(function(item) {
    return item.name === curr.name;

  })
  if (findIndexs === -1) {
    let obj = {
      name: curr.name,
      description: curr.description
    }
    acc.push(obj)
  } else {
    acc[findIndexs].description = acc[findIndexs].description + ' \n ' + curr.description
  }
  return acc;
}, []);
console.log(newArray)

【讨论】: