繁体   English   中英

如何计算数组中的相同对象属性值

[英]how to count same object attribute values in array

我有一个大型数组,具有以下结构:

let data = [
  {
    name: 'name1',
    values: {...},
  },
  {
    name: 'name1',
    values: {...},
  },
  {
    name: 'name2',
    values: {...},
  },
  {
    name: 'name1',
    values: {...},
  },
  {
    name: 'name3',
    values: {...},
  },
  ...
]

我需要找到一种方法来计算每个名称在数据数组中作为名称值出现的频率。

因此,在此示例中,结果应如下所示:

let nameCounts = [
  {
     name: 'name1'
     count: 3
  },
  {
     name: 'name2'
     count: 1
  },
  {
     name: 'name3'
     count: 1
  }
]

我正在努力为这个问题找到好办法。 有任何想法吗?

您可以reduce数组reduce为名称为键的对象,并将“计数对象”作为值。 然后你可以用Object.values得到你的最终数组:

 let data = [{ name: 'name1', values: {}, }, { name: 'name1', values: {}, }, { name: 'name2', values: {}, }, { name: 'name1', values: {}, }, { name: 'name3', values: {}, } ]; var res = Object.values(data.reduce((a, {name}) => { a[name] = a[name] || {name, count: 0}; a[name].count++; return a; }, Object.create(null))); console.log(res); 

请注意,我使用对象解构来从reduce回调中的每个“当前”对象获取name值。 || 模式是JS land中的标准做法,如果它不存在则分配默认值。

另请注意@ ibrahimmahrir关于使用Object.create(null)为累加器创建无原型对象的注释。

使用Array#reduceArray#map替代解决方案。

 const data = [{name:'name1'},{name:'name1'},{name:'name2'},{name:'name1'},{name:'name3'}]; const q = data.reduce((s, { name }) => (s[name] = (s[name] || 0) + 1, s), {}); const r = Object.keys(q).map((key) => ({ name: key, count: q[key] })); console.log(r); 

我将使用Array.prototype.reduce()创建一个name part作为键的对象,让计数累积为该对象的值,然后使用Object.prototype.entries()将其转换回数组。

const reducer = (acc, {name}) => {
    acc[name] = acc[name] || 0
    acc[name] += 1
    return acc
}

data.reduce(reducer, {})
    .entries()
    .forEach(([name, count]) => { name, count})

另一种方法是使用Array.reduceMap因为Map真的是为这个做的孩子:)

 let data = [{ name: 'name1', values: {}, }, { name: 'name1', values: {}, }, { name: 'name2', values: {}, }, { name: 'name1', values: {}, }, { name: 'name3', values: {}, } ]; const countBy = (arr, prop) => arr.reduce((r,c,i,a) => { r.set(c[prop], (r.get(c[prop]) || 0) + 1) return i == a.length-1 ? Array.from(r).map(([k,v]) => ({ name: k, count: v })) : r }, new Map()) console.log(countBy(data, 'name')) 

我以一种模仿lodash _.countBy (如果你使用的方式不会比这更简洁)的函数形式制作,但输出略有不同:

 let data = [{ name: 'name1', values: {}, }, { name: 'name1', values: {}, }, { name: 'name2', values: {}, }, { name: 'name1', values: {}, }, { name: 'name3', values: {}, } ]; console.log(_.countBy(data, 'name')) 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script> 

暂无
暂无

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

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