Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Summarize the frequency of array of objects

Assume I have the following array of objects.

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

what I need is to summarize the frequency of identical object in the array. The output will look like:

summary = [
  { x: 1, y: 1, f: 3 },
  { x: 1, y: 2, f: 1 },
  { x: 2, y: 2, f: 2 },
  { x: 3, y: 3, f: 1 }
]

For now I have this code

const summary = data.map((item, index, array) => {
  return { x: item.x, y: item.y, f: array.filter(i => i === item).length };
});

But I suppose I can do better by using reduce or includes. Any ideas?

like image 863
kemakino Avatar asked Dec 17 '22 16:12

kemakino


1 Answers

Reduce into an object whose keys uniquely represent an object, whose values are the object (with x, y, and f properties). On each iteration, increment the appropriate key's f property, or create the key on the accumulator if it doesn't exist yet:

const data = [
  { x: 1, y: 1 },
  { x: 2, y: 2 },
  { x: 3, y: 3 },
  { x: 2, y: 2 },
  { x: 1, y: 1 },
  { x: 1, y: 2 },
  { x: 1, y: 1 }
];
const countObj = data.reduce((a, obj) => {
  const objString = obj.x + '_' + obj.y;
  if (!a[objString]) {
    a[objString] = { ...obj, f: 1 };
  } else {
    a[objString].f++;
  }
  return a;
}, {});
const output = Object.values(countObj);
console.log(output);
like image 158
CertainPerformance Avatar answered Jan 03 '23 11:01

CertainPerformance