Объединение вложенных массивов и удаление дубликатов

Как мне объединить эти наборы массивов, чтобы они были объединены вместе и не было повторяющихся значений?

Не уверен, что у lodash есть что-то, чтобы помочь с этим, большинство других ответов, которые я нашел, основаны на том, что массивы являются плоскими, но в этой структуре моего набора данных они вложены.

Спасибо за вашу помощь!

let arr1 = [
  ["name", "id", 'age'],
  ["Susan", "3", '20'],
  ["John", "1", '21'],
  ["Bob", "2", '23'],
  ["Ben", "4", '20']
];

let arr2 = [
  ["name", "id", 'height'],
  ["Bob", "2", '50'],
  ["John", "1", '45'],
  ["Ben", "4", '43'],
  ["Susan", "3", '48'],
];

let arr3 = [
  ["name", "id", 'parent'],
  ["Bob", "2", 'yes'],
  ["John", "1", 'yes'],
];


//desired output
// [
//   ['name', 'id', 'age', 'height', 'parent'],
//   ["Susan", "3", '20', '48', ''],
//   ["John", "1", '21', '45', 'yes'],
//   ["Bob", "2", '23', '50', 'yes'],
//   ["Ben", "4", '20', '43', '']
// ]
Поведение ключевого слова "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) для оценки ваших знаний,...
2
0
1 213
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Используя lodash flatten и uniq

Flatten объединяет массивы в сглаженный массив.

_.uniq(_.flatten([arr1, arr2, arr2));

Теперь это отвечает на заголовок и текст вашего вопроса, но, судя по желаемому результату, вас ждут тяжелые времена. То, что я изложил, не даст такого результата.

Вы можете изучить функцию Lodash merge, но то, что вы делаете, намного проще делать с объектами, а не с массивами.

Я согласен с вами... это будет тяжело 😰

Brock 10.12.2020 20:53

Рассматривали ли вы возможность превратить имеющиеся у вас массивы в объекты? Лучше всего сделать это, а затем использовать lodash mergeWith.

Slbox 10.12.2020 21:19

Объедините таблицы, преобразовав строки в объекты и объединив их с помощью Array.reduce() и карты (чтобы сохранить исходный порядок). Сохраните заголовки и объедините их с помощью _.union() (или набора). Затем верните массив, содержащий комбинированные заголовки, а строки основного текста преобразуются в массивы с помощью Array.mpa() и комбинированных заголовков.

// convert table rows to objects
const tableRowsToObjects = ([head, ...body]) => [head, body.map(row => _.zipObject(head, row))]

// combine tables' headers & bodies
const combineTables = tables => {
  const header = _.union(..._.map(tables, _.head))

  const body = Array.from(
    tables
      .flatMap(([, rows]) => rows)
      .reduce((acc, row) => acc.set(row.id, { ...acc.get(row.id), ...row }), new Map)
      .values()
  )

  return [header, body]
}

// convert tables to objects, merge them, and then convert back to rows
const mergeTables = (...tables) => {
  const [header, body] = combineTables(tables.map(tableRowsToObjects))
  
  return [
    header,
    ...body.map(row => header.map(col => row[col] ?? ''))
  ];
}

const arr1 = [["name","id","age"],["Susan","3","20"],["John","1","21"],["Bob","2","23"],["Ben","4","20"]];
const arr2 = [["name","id","height"],["Bob","2","50"],["John","1","45"],["Ben","4","43"],["Susan","3","48"]];
const arr3 = [["name","id","parent"],["Bob","2","yes"],["John","1","yes"]];

const result = mergeTables(arr1, arr2, arr3);

console.info(result);
<script src = "https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js" integrity = "sha512-90vH1Z83AJY9DmlWa8WkjkV79yfS2n2Oxhsi2dZbIv0nC4E6m5AbH8Nh156kkM7JePmqD6tcZsfad1ueoaovww= = " crossorigin = "anonymous"></script>
Ответ принят как подходящий

Вы можете сделать это в ванильном JavaScript. Сначала превратите все три массива в объект, используя метод сокращения. Затем снова с помощью метода сокращения получите уникальный объединенный объект. Наконец, сделайте объект массивом.

const arr1 = [
  ['name', 'id', 'age'],
  ['Susan', '3', '20'],
  ['John', '1', '21'],
  ['Bob', '2', '23'],
  ['Ben', '4', '20'],
];

const arr2 = [
  ['name', 'id', 'height'],
  ['Bob', '2', '50'],
  ['John', '1', '45'],
  ['Ben', '4', '43'],
  ['Susan', '3', '48'],
];

const arr3 = [
  ['name', 'id', 'parent'],
  ['Bob', '2', 'yes'],
  ['John', '1', 'yes'],
];

const makeObject = (arr) => {
  const props = arr.slice(0, 1).flat();
  return arr.slice(1).map((x) => {
    return props.reduce((prev, c, i) => {
      const p = prev;
      p[c] = x[i];
      return p;
    }, {});
  });
};

const objArray = Object.values(
  [...makeObject(arr1), ...makeObject(arr2), ...makeObject(arr3)].reduce(
    (prev, c) => {
      const p = prev;
      const key = c.id;
      if (!p[key])
        p[key] = {
          ...{ name: '', id: '', age: '', height: '', parent: '' },
          ...c,
        };
      else p[key] = { ...p[key], ...c };
      return p;
    },
    {}
  )
);
const ret = objArray.map((x) => Object.values(x));
ret.unshift(Object.keys(objArray[0]));
console.info(ret);

Я предлагаю сначала создать объект. Синтаксис ES6 позволяет сделать это в несколько строк. Это также решает проблему унификации.

const addData = ([head, ...data], obj = {}) => (
  data.reduce((acc, [name, id, value]) => ({
    ...acc,
    [id]: {
      ...acc[id],
      name, [head[2]]: value
    }
  }), obj)
)

// -------

const arr1 = [
  ["name", "id", 'age'],
  ["Susan", "3", '20'],
  ["John", "1", '21'],
  ["Bob", "2", '23'],
  ["Ben", "4", '20']
];

const arr2 = [
  ["name", "id", 'height'],
  ["Bob", "2", '50'],
  ["John", "1", '45'],
  ["Ben", "4", '43'],
  ["Susan", "3", '48'],
];

const arr3 = [
  ["name", "id", 'parent'],
  ["Bob", "2", 'yes'],
  ["John", "1", 'yes'],
];


let indexedObj = {}
indexedObj = addData(arr1, indexedObj)
indexedObj = addData(arr2, indexedObj)
indexedObj = addData(arr3, indexedObj)

console.info(indexedObj)

Затем используйте метод создания массива mr hr.

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