#javascript #lodash
Вопрос:
Я задаюсь вопросом и пытаюсь понять, как фильтровать повторяющиеся объекты массива, но не удаляя повторяющиеся элементы, а вместо этого сохраняя их в массиве внутри возвращаемых элементов, я не уверен, понятно ли то, что я говорю, поэтому пример будет полезен: мои данные:
[{letter: 'a', number: 1}, {letter: 'a', number: 2}, {letter: 'a', number: 3}, {letter: 'b', number: 1}, {letter: 'b', number: 2}, {letter: 'a', number: 4}, {letter: 'b', number: 1}, {letter: 'a', number: 3}]
что я ожидаю получить:
[{
letter: 'a',
numbers: [{number: 1}, {number: 2}, {number: 3}, {number: 4}],
}, {
letter: 'b',
numbers: [{number: 1}, {number: 2}],
}]
Я знаю, что мы ищем ответы, но объяснение было бы отличным.
Комментарии:
1. Более разумный ожидаемый формат вывода значительно облегчил бы достижение этой цели. Почему бы просто не:
{a: [1, 2, 3, 4], b: [1, 2]}
? Для этого также вряд ли требуется lodash.2. Я упростил свою задачу, мои объекты намного больше, но с примером для них более чем достаточно.
Ответ №1:
Сгруппируйте по letter
, а затем сопоставьте группы с объектом. Создайте числа, сопоставив значения и опустив letter
:
const { map, groupBy, omit } = _
const arr = [{letter: 'a', number: 1}, {letter: 'a', number: 2}, {letter: 'a', number: 3}, {letter: 'b', number: 1}, {letter: 'b', number: 2}, {letter: 'a', number: 4}, {letter: 'b', number: 1}, {letter: 'a', number: 3}]
const result = map(
groupBy(arr, 'letter'),
(numbers, letter) => ({
letter,
numbers: map(numbers, o => omit(o, 'letter')),
})
)
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.js" integrity="sha512-2iwCHjuj PmdCyvb88rMOch0UcKQxVHi/gsAml1fN3eg82IDaO/cdzzeXX4iF2VzIIes7pODE1/G0ts3QBwslA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
Ответ №2:
Вы можете использовать array.reduce
метод
arr.reduce((acc, {letter,number}) => {
let obj = acc.find(a => a.letter === letter);
obj
? obj.numbers.push({number})
: acc.push({ letter,numbers:[{number}]});
return acc;
}
, [])