Javascript – Counting duplicates in object array and storing the count as a new object

I would stick to reduce, use a Map and spread its values to get the final result:

const names = [{  _id: 1 }, { _id: 1}, { _id: 2}, { _id: 1}];

const result = [...names.reduce( (mp, o) => {
    if (!mp.has(o._id)) mp.set(o._id, { ...o, count: 0 });
    mp.get(o._id).count++;
    return mp;
}, new Map).values()];

console.log(result);

Or you can first create all the keys in the map with a zero count (using the Map constructor), and then iterate the data again to update the counter. This split of tasks makes the code more concise than with reduce:

const names = [{  _id: 1 }, { _id: 1}, { _id: 2}, { _id: 1}];

const mp = new Map(names.map(o => [o._id, {...o, count: 0 }]));
for (const {_id} of names) mp.get(_id).count++;
const result = Array.from(mp.values());

console.log(result);

When you would have more than one key, then one idea is to join those with JSON.stringify([ ]):

const names = [{cat: 1, sub: 1}, {cat: 1, sub: 2}, {cat: 2, sub: 1}, {cat: 1, sub: 1}];

const result = [...names.reduce( (mp, o) => {
    const key = JSON.stringify([o.cat, o.sub]);
    if (!mp.has(key)) mp.set(key, { ...o, count: 0 });
    mp.get(key).count++;
    return mp;
}, new Map).values()];

console.log(result);

Leave a Comment