3

I have object array like this.

const array = [ { x: 1, y: 2 }, { x: 3, y: 4 }, { x: 1, y: 2 }, { x: 3, y: 4 }, { x: 1, y: 2 }, { x: 3, y: 12 } ]

I want to count duplicates objects and store the count as new object field.

I found this snippet and it work great but it not exactly what i need.

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, Object.assign({ count: 0 }, o));
    mp.get(o._id).count++;
    return mp;
    }, new Map).values()];

    console.log(result);

It works with object with one field _id. In my case there are two, x and y

How should I modify that code?

In brief...I would like to receive the result:

result = [ { x: 1, y: 2, count:3 }, { x: 3, y: 4, count:2 }, { x: 3, y: 12, count:1 } ]
bastej
  • 83
  • 1
  • 5
  • Possible duplicate of [How to count duplicate value in an array in javascript](https://stackoverflow.com/questions/19395257/how-to-count-duplicate-value-in-an-array-in-javascript) – Jared Smith Dec 12 '17 at 14:13
  • 1
    You can use `JSON.stringify([o.x, o.y])` or `o.x+'|'+o.y` instead of `o._id` - anything that uniquely identifies your objects and fits your data types – Bergi Dec 12 '17 at 14:18

2 Answers2

6

You can use Object.values() and reduce() methods to return new array of objects.

const array = [ { x: 1, y: 2 }, { x: 3, y: 4 }, { x: 1, y: 2 }, { x: 3, y: 4 }, { x: 1, y: 2 }, { x: 3, y: 12 } ]

const result = Object.values(array.reduce((r, e) => {
  let k = `${e.x}|${e.y}`;
  if(!r[k]) r[k] = {...e, count: 1}
  else r[k].count += 1;
  return r;
}, {}))

console.log(result)

Here is the solution with Map and spread syntax ...

const array = [ { x: 1, y: 2 }, { x: 3, y: 4 }, { x: 1, y: 2 }, { x: 3, y: 4 }, { x: 1, y: 2 }, { x: 3, y: 12 } ]

const result = [...array.reduce((r, e) => {
  let k = `${e.x}|${e.y}`;
  if(!r.has(k)) r.set(k, {...e, count: 1})
  else r.get(k).count++
  return r;
}, new Map).values()]

console.log(result)
Nenad Vracar
  • 118,580
  • 15
  • 151
  • 176
3

One way to do it would be to create an index mapping both x and y to the result entry:

let index = { };
let result = [ ];
const array = [ { x: 1, y: 2 }, { x: 3, y: 4 }, { x: 1, y: 2 }, { x: 3, y: 4 }, { x: 1, y: 2 }, { x: 3, y: 12 } ];
array.forEach(point => {
    let key = '' + point.x + '||' + point.y;
    if (key in index) {
        index[key].count++;
    } else {
        let newEntry = { x: point.x, y: point.y, count: 1 };
        index[key] = newEntry;
        result.push(newEntry);
    }
});
console.log(result);
xs0
  • 2,990
  • 17
  • 25
  • can i use conditions `in` to count the values of object like this ```let data = [{ no: 3, name: 'drink' }, { no: 90, name: 'eat' }, { no: 20, name: 'swim' } ];``` – Zum Dummi Jan 19 '19 at 01:42