Сгруппировать объекты в массиве
Есть массив с объектами. Необходимо его сгруппировать по имени, а значения ключей суммировать, если имя совпадает. Сделал флаг, который фильтрует повторения. А вот с тем, как суммировать значения, разобраться не могу.
Дано:
[{
name: 'aaa',
coin: 30
},
{
name: 'bbb',
coin: 32
},
{
name: 'aaa',
coin: 20
},
{
name: 'aaa',
coin: 50
}]
Результат должен быть таким:
[{name: 'aaa', coin: 100}, {name: 'bbb', coin: 32}]
Мой код:
const arr = [{
name: 'aaa',
price: 30
},
{
name: 'bbb',
price: 32
},
{
name: 'aaa',
price: 20
},
{
name: 'aaa',
price: 50
}];
const myFunction = (arr) => {
let result = [];
arr.forEach(object => {
let flag = false;
result.forEach((objectResult, index) => {
if (object.name === objectResult.name){
flag = true;
}
});
if (!flag) result.push(object);
});
return result; };
const test = myFunction(arr); console.log(test);
Ответы (2 шт):
Можно так.
Проходимся по массиву при помощи .reduce() с начальным аккумулятором в виде пустого объекта. На каждой итерации проверяем, нет ли в нашем аккумуляторе ключа, равного name. Если нет, создаём ключ с начальным значением { name: name, coin: 0 }. Проверку и создание можно сократить до одного шага при помощи ??=. Теперь мы можем плюсовать значения coin в этом объекте. В конце нам останется только превратить аккумулятор в массив объектов c сумами при помощи Object.values().
const array = [{
name: 'aaa',
coin: 30
},
{
name: 'bbb',
coin: 32
},
{
name: 'aaa',
coin: 20
},
{
name: 'aaa',
coin: 50
}];
const array2 = Object.values(array.reduce(
(acc, { name, coin }) => {
acc[name] ??= { name, coin: 0 };
acc[name].coin += coin;
return acc;
},
{},
));
console.log(array2);
Код немного попроще. Алгоритм тот же самый, что и у ответа @vsemozhebuty
const array = [{
name: 'aaa',
coin: 30
},
{
name: 'bbb',
coin: 32
},
{
name: 'aaa',
coin: 20
},
{
name: 'aaa',
coin: 50
}
];
const resultObject = {};
for (let item of array) {
const resultValue = resultObject[item.name];
if (resultValue) {
// у нас такой уже есть, плюсуем
resultValue.coin += item.coin;
} else {
// такого еще нету - создаем новый
resultObject[item.name] = { ...item };
}
}
const resultArray = Object.values(resultObject);
console.log(resultArray);