繁体   English   中英

如果对象属性相同,则将数组中的两个对象组合到单个对象中,并将唯一属性转换为数组

[英]Combine two objects in an array into a single object if the object properties are the same and convert the unique properties into an array

输入 -

[
  {color:'red', shape:'circle', size:'medium'},
  {color:'red', shape:'circle', size:'small'}
]

输出 -

[
  {color:'red', shape:'circle', size:['medium','small']}
]

如何在Javascript中实现这一目标?

您可以创建一个通用函数,它将对象数组和键数组作为参数进行匹配。

您可以通过以下步骤执行此操作:

  • 首先在对象数组上使用reduce()并将accumulator设置为empty array []
  • 通过在Object.keys()上使用filter()获取其他道具(独特的道具Object.keys()
  • 然后在每次迭代中找到累加器数组的元素,其所有给定的props与当前对象匹配。
  • 如果找到该元素,则使用forEach()其他键并将值推送到相应的数组。
  • 如果未找到element,则将每个键设置为空数组。
  • 最后返回reduce()的结果

 const arr = [ {color:'red', shape:'circle', size:'medium'}, {color:'red', shape:'circle', size:'small'} ] function groupByProps(arr,props){ const res = arr.reduce((ac,a) => { let ind = ac.findIndex(b => props.every(k => a[k] === b[k])); let others = Object.keys(a).filter(x => !props.includes(x)); if(ind === -1){ ac.push({...a}); others.forEach(x => ac[ac.length - 1][x] = []); ind = ac.length - 1 } others.forEach(x => ac[ind][x].push(a[x])); return ac; },[]) return res; } const res = groupByProps(arr,['color','shape']) console.log(res) 

如果您只想根据colorshape进行分组,可以使用reduce 使用由|分隔的这两个属性的每个唯一组合创建一个累加器对象 作为关键。 并将输出中的对象作为其值。 然后使用Object.values()将这些对象作为数组。

 const input = [ {color:'red', shape:'circle', size :'medium'}, {color:'red', shape:'circle', size:'small'}, {color:'blue', shape:'square', size:'small'} ]; const merged = input.reduce((acc, { color, shape, size }) => { const key = color + "|" + shape; acc[key] = acc[key] || { color, shape, size: [] }; acc[key].size.push(size); return acc }, {}) console.log(Object.values(merged)) 

这就是merged / accumulator的样子:

{
  "red|circle": {
    "color": "red",
    "shape": "circle",
    "size": [
      "medium",
      "small"
    ]
  },
  "blue|square": {
    "color": "blue",
    "shape": "square",
    "size": [
      "small"
    ]
  }
}

您可以通过创建要分组的键数组使其动态化:

 const input = [ { color: 'red', shape: 'circle', size: 'medium' }, { color: 'red', shape: 'circle', size: 'small' }, { color: 'blue', shape: 'square', size: 'small' } ]; const groupKeys = ['color', 'shape']; const merged = input.reduce((acc, o) => { const key = groupKeys.map(k => o[k]).join("|"); if (!acc[key]) { acc[key] = groupKeys.reduce((r, k) => ({ ...r, [k]: o[k] }), {}); acc[key].size = [] } acc[key].size.push(o.size) return acc }, {}) console.log(Object.values(merged)) 

这是一个简单的groupBy函数,它接受一组对象和一组props来分组:

 let data = [ {color:'red', shape:'circle', size:'medium'}, {color:'red', shape:'circle', size:'small'} ] let groupBy = (arr, props) => Object.values(arr.reduce((r,c) => { let key = props.reduce((a,k) => `${a}${c[k]}`, '') let otherKeys = Object.keys(c).filter(k => !props.includes(k)) r[key] = r[key] || {...c, ...otherKeys.reduce((a,k) => (a[k] = [], a),{})} otherKeys.forEach(k => r[key][k].push(c[k])) return r }, {})) console.log(groupBy(data, ['color','shape'])) 

这个想法是使用Array.reduce并基本上创建传入的道具的字符串键。 对于其他字段,创建一个数组并在每次迭代时继续推送值。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM