I have a large array with the following structure:
let data = [
{
name: 'name1',
values: {...},
},
{
name: 'name1',
values: {...},
},
{
name: 'name2',
values: {...},
},
{
name: 'name1',
values: {...},
},
{
name: 'name3',
values: {...},
},
...
]
I need to find a way to count how often each name appears as a name value inside the data array.
So in this example the result should look like the following array:
let nameCounts = [
{
name: 'name1'
count: 3
},
{
name: 'name2'
count: 1
},
{
name: 'name3'
count: 1
}
]
I'm struggling to find good way for this problem. Any ideas?
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.
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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With