0

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'],
  },
];
DarkBee
  • 16,592
  • 6
  • 46
  • 58
evll
  • 97
  • 3
  • 12

5 Answers5

3

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);
Tushar Shahi
  • 16,452
  • 1
  • 18
  • 39
1

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 
Jacob Shore
  • 115
  • 9
1
  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;
}
  , []);
Parvesh Kumar
  • 1,104
  • 7
  • 16
1

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});
}
igor Smirnov
  • 188
  • 2
  • 8
1
let results = [];
const arr = [
  {
    name: "A",
    color: "blue",
  },
  {
    name: "A",
    color: "purple",
  },
  {
    name: "B",
    color: "Yellow",
  },
  {
    name: "B",
    color: "Green",
  },
];
const names = arr.map((element) => element.name);
const uniqueNames = [...new Set(names)];
uniqueNames.forEach((element) => {
  let temp = {};
  temp.name = element;
  temp.color = [];
  arr.forEach((element2) => {
    if (element === element2.name) {
      temp.color.push(element2.color);
    }
  });
  results.push(temp);
});

console.log("results", results);