'In an array of objects how to group objects which have same value and include the values that differ [duplicate]

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'],
  },
];


Solution 1:[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;
}
  , []);

Solution 2:[2]

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 

Solution 3:[3]

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});
}

Solution 4:[4]

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);

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Parvesh Kumar
Solution 2
Solution 3 igor Smirnov
Solution 4 Mohammad Fareed Alam