Home > Mobile >  In an array of objects how to group objects which have same value and include the values that differ
In an array of objects how to group objects which have same value and include the values that differ

Time:02-02

I have an array of objects and I would like to group the objects which have same name and make an array containing the other values which differs. How can I achieve that?

const arr = [
  {
    name: 'A',
    color: 'blue',
  },
  {
    name: 'A',
    color: 'purple',
  },
  {
    name: 'B',
    color: 'Yellow',
  },
  {
    name: 'B',
    color: 'Green',
  },
];

What I would like to get:

const result = [
  {
    name: 'A',
    color: ['blue', 'purple'],
  },
  {
    name: 'B',
    color: ['Yellow', 'Green'],
  },
];

CodePudding user response:

  const found = acc.find(item => item.name === curr.name);
  if (found) {
    found.color.push(curr.color);
  } else {
    acc.push({
      name: curr.name,
      color: [curr.color],
    });
  }
  return acc;
}
  , []);

CodePudding user response:

Here is one way to do it:

const arrNames = Array.from(new Set(arr.map((x) => x.name))); // make an array of unique names
const result = arrNames
  .map((x) => arr.filter((y) => y.name === x)) // filter by name
  .map((x, i) => ({ name: arrNames[i], color: x.map((y) => y.color) })); // make new objects 

CodePudding user response:

This looks like something reduce() should be used for. Use find() to find in the existing array element based on some condition. If element exists, push into colors property of the element. Else push into the array a new object.

const arr = [
  {
    name: 'A',
    color: 'blue',
  },
  {
    name: 'A',
    color: 'purple',
  },
  {
    name: 'B',
    color: 'Yellow',
  },
  {
    name: 'B',
    color: 'Green',
  },
];


let ans = arr.reduce((agg,curr) => {
let found = agg.find((x) => x.name === curr.name);
if(found){
  found.colors.push(curr.color);
}
else{
   agg.push({
   name : curr.name,
   colors : [curr.color]
   });
}
return agg;
},[]);

console.log(ans);

CodePudding user response:

Create set of props then loop over possible names and filter their values O(n^2)

const set = new Set(arr.map((obj) => obj.name));
const res = [];
for(const name of set.keys()) {
  const colors = arr.filter((obj) => obj.name === name).map((obj) => obj.color);
  res.push({name, colors});
}

Or create a dictionary whose keys will be name-s, and values - array O(n)

const mp = new Map();
for (const obj of arr) {
    if (mp.has(obj.name)) {
        mp.get(obj.name).push(obj.color);
    } else {
        mp.set(obj.name, [obj.color]);
    }
}
const result = [];
for (const [name, color] of mp.entries()) {
 result.push({name, color});
}
  •  Tags:  
  • Related