Как сформировать новый массив объектов, сделав слияние по некоторому параметру?
хочу сформировать новый массив объектов из старого, используя js, возможно даже лучше lodash
у меня есть некоторая сущность:
const arr = [
{merch: 111, games: ['loto1', 'loto2']},
{merch: 111, games: ['loto2', 'loto3']},
{merch: 222, games: ['loto3', 'loto4']},
];
массив состоит из объектов, у них могут быть схожие значения в поле merch и общие значения в games как сформировать новый массив, объединив в нем объекты по полю merch? при этом без дубликатов на выходе хочу иметь подобное
=> [
{merch: 111, games: ['loto1', 'loto2', 'loto3']},
{merch: 222, games: ['loto3', 'loto4']},
]
пытался сделать через reduce из библиотеки lodash, но не до конца понимаю как это сделать
Ответы (1 шт):
Описание логики:
Начинаем с reduce:
- Результат будем записывать в словарик Map. Можно заменить и на обычный объект, если надо, просто код, немного нагромоздится
- Смотрим, если у нас нет ключа
merch, то просто записываем в словарик, новый ключmerchи значение набор Set изgames. Тут так же можно обойтись обычным объектом например, но опять таки это нагромоздит код - Если есть такой ключ в словарике, то просто добавляем в набор все новые значения. Удобство
Set-а в том, что он сам автоматически добавляет только уникальные значения
На выходе получаем
Map, потому можем у него взять все наборы ключей-значений с помощью entries()Получаем массив с помощью spread, так же можно было воспользоваться и Array.from()
Ну и самое простое, превращаем элементы массива в объекты нужного нам вида с помощью map()
- Так как в значениях словарика у нас хранились наборы, то преобразуем их обратно в массивы с помощью
spread, так же можно было воспользоваться иArray.from()
- Так как в значениях словарика у нас хранились наборы, то преобразуем их обратно в массивы с помощью
Код:
const arr = [{
merch: 111,
games: ['loto1', 'loto2']
},
{
merch: 111,
games: ['loto2', 'loto3']
},
{
merch: 222,
games: ['loto3', 'loto4']
},
];
const uniqueArr = [...arr.reduce((result, el) => {
if (!result.has(el.merch)) {
return result.set(el.merch, new Set(el.games))
}
const merch = result.get(el.merch);
for (const game of el.games) merch.add(game)
return result;
}, new Map()).entries()].map(item => ({
merch: item[0],
games: [...item[1]]
}));
console.log(uniqueArr);