How To Count Same Object Attribute Values In Array
Solution 1:
You can reduce
your array to an object that has names as keys and "count objects" as values. Then you can get your final array with 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);
Note that I use object destructuring to get the name
value from each "current" object in the reduce callback. And the ||
pattern is standard practice in JS land to assign a default if it's not present.
Also note @ibrahimmahrir's comment about using Object.create(null)
to create a prototypeless object for the accumulator.
Solution 2:
Alternative solution using Array#reduce
and Array#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);
Solution 3:
I would use Array.prototype.reduce() to create an object with the name
part as the key and let the counts accumulate as the values of that object, and then use Object.prototype.entries() to transform this back into an array.
const reducer = (acc, {name}) => {
acc[name] = acc[name] || 0
acc[name] += 1
return acc
}
data.reduce(reducer, {})
.entries()
.forEach(([name, count]) => { name, count})
Solution 4:
Another approach to this would be with Array.reduce
and Map
since Map
is kid of made for this really :)
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'))
I made it in a form of a function mimicking what lodash
_.countBy (which if you are using you wont get more concise than that) does but with slightly different output:
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>
Post a Comment for "How To Count Same Object Attribute Values In Array"