Как лучше всего объединить вложенные массивы

У меня есть массив объектов, который выглядит так:

[
 {external_id: 1, items: [{k: 'v'}] },
 {external_id: 2, items: [{k1: 'v1'}] },
 {external_id: 1, items: [{k2: 'v2'}, {k3: 'v3'}] }
]

Что я хочу сделать, так это объединить вложенные массивы на основе external_id и вернуть «чистый массив», который будет выглядеть так:

[
 {external_id: 1, items: [{k: 'v'}, {k2: 'v2'}, {k3: 'v3'}] },
 {external_id: 2, items: [{k1: 'v1'}] }
]

Итак, мой вопрос: как это сделать без использования классического цикла for?

какой длины массивы?

germanio 18.12.2020 18:41

массивы не имели бы length >= 10

yury_hr 18.12.2020 18:44

Я настоятельно рекомендую вам прочитать документацию по массивам javascript: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… и основам работы с объектами: developer.mozilla.org/en-US. /docs/Learn/JavaScript/Objects/…

germanio 18.12.2020 18:48
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
3
66
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Вам придется зацикливаться. Вы можете зацикливаться с помощью for, forEach, map, reduce, find, ... и т. д., но вам придется зацикливаться.

Вот способ, который создает карту с ключом external_id, а затем заполняет эту карту элементами. Наконец, значения этой карты представляют результат:

let data = [{external_id: 1, items: [{k: 'v'}] },{external_id: 2, items: [{k1: 'v1'}] },{external_id: 1, items: [{k2: 'v2'}, {k3: 'v3'}] }];

let map = new Map(data.map(({external_id}) => [external_id, { external_id, items:[] }]));
data.forEach(o => map.get(o.external_id).items.push(...o.items));
let result = [...map.values()];
console.info(result);

Использование сокращения и сортировки

let data = [{
    external_id: 1,
    items: [{
      k: 'v'
    }]
  },
  {
    external_id: 2,
    items: [{
      k1: 'v1'
    }]
  },
  {
    external_id: 1,
    items: [{
      k2: 'v2'
    }, {
      k3: 'v3'
    }]
  },
];

let ans = data
  .sort(function(a, b) {
    return a['external_id'] - b['external_id'];
  })
  .reduce((acc, currentObject) => {
    const endObject = acc[acc.length - 1];
    if (endObject && endObject['external_id'] === currentObject.external_id) {
      endObject.items.push(...currentObject.items);
    } else {
      acc.push({ ...currentObject
      });
    }
    return acc;
  }, []);
console.info(ans);

спасибо, это тоже хорошее решение. Хотел бы я отметить оба ответа принятыми :)

yury_hr 18.12.2020 20:09

использование другого объекта для группировки объектов с одним и тем же свойством external_id

let a = [
    {external_id: 1, items: [{k: 'v'}] },
    {external_id: 2, items: [{k1: 'v1'}] },
    {external_id: 1, items: [{k2: 'v2'}, {k3: 'v3'}] }
]

let obj = {};

a.forEach( ({external_id, items}) => {
    obj[external_id] ??= new Set;
    items.map( i => {
        obj[external_id].add(JSON.stringify(i));
    });
});

a = Object.keys(obj).map( (n) => {
    n = Number(n);
    return {
        external_id:n,
        items: [...obj[n]].map(JSON.parse)
    }
})

Другие вопросы по теме