Как я могу фильтровать повторяющиеся элементы в массиве, не удаляя их с помощью lodash?

#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; 
                                       }
           , [])