3

im trying to add counting number for duplicate in JS. and i am completely stack in this case below. i need to compare objects with two value (x, y) and if there are same values of (x, y) add count 1 on new objects.

is there any way to convert data to newData such as below?

const data = [
    {id: 1, x: 1, y: 1},
    {id: 2, x: 2, y: 2},
    {id: 3, x: 1, y: 1},
]

const newData = [
    {x: 1, y:1 ,count:2}
    {x: 2, y:2 ,count:1}
]
D1212
  • 31
  • 1

4 Answers4

2

use .reduce() function

const data = [
    {id: 1, x: 1, y: 1},
    {id: 2, x: 2, y: 2},
    {id: 3, x: 1, y: 1},
]

const output = data.reduce((acc, curr) => {
  curr.count = 1;
  const exists = acc.find(o => o.x === curr.x && o.y === curr.y);
  
  exists ? exists.count++ : acc.push(({ x, y, count } = curr));
  
  return acc;
}, []);

console.log(output);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Yousaf
  • 27,861
  • 6
  • 44
  • 69
0

One way of doing so, is to create a map with the x and y values, and increment the count accordingly, then convert the map into an array:

    const data = [
        {id: 1, x: 1, y: 1},
        {id: 2, x: 2, y: 2},
        {id: 3, x: 1, y: 1},
    ]
    
    const makeXYMap =  (data) => data.reduce((acc, cur) => {
      const { x, y } = cur;
      const entry = acc[`${x}_${y}`];
      
      if (entry) {
     acc[`${x}_${y}`] = {...entry, count: entry.count + 1};
      } else {
       acc[`${x}_${y}`] = { x, y, count: 1 };
      }
    
      return acc;
    }, {});
    
    const makeArray = (XYMap) => Object.values(XYMap);
    
    console.log(makeArray(makeXYMap(data)));

Note that complexity wise, this solution is a O(N).

https://jsfiddle.net/9o35neg7/

MorKadosh
  • 5,846
  • 3
  • 25
  • 37
0

const data = [
  { id: 1, x: 1, y: 1 },
  { id: 2, x: 2, y: 2 },
  { id: 3, x: 1, y: 1 },
  // .. so on ..
];

const countedData = data.reduce((acc, { x, y }, index, array) => {
  acc[`x${x}y${y}`] = {
    x,
    y,
    count: (acc[`x${x}y${y}`] ? acc[`x${x}y${y}`].count : 0) + 1
  };

  return index === (array.length - 1) ? Object.values(acc) : acc;
}, {});

console.log(countedData);
Kharel
  • 819
  • 8
  • 16
0

Use forEach and build an object with key (made of x, y) and values (aggregate count). Get the Object.values to get the results as array.

const data = [
    {id: 1, x: 1, y: 1},
    {id: 2, x: 2, y: 2},
    {id: 3, x: 1, y: 1},
]

const counts = (arr, res = {}) => {
  arr.forEach(({x , y}) => 
    res[`${x}-${y}`] = { x, y, count: (res[`${x}-${y}`]?.count ?? 0) + 1 })
  return Object.values(res);
}

console.log(counts(data))
Siva K V
  • 10,561
  • 2
  • 16
  • 29
  • thank you very much for the code and explanation! this one is also simple to understand !!!! – D1212 Jun 18 '20 at 01:51