Пересечение, разница, слияние двух массивов в JavaScript ES6

Пересечение, разница, слияние двух массивов в JavaScript ES6

В этой статье я решил поделиться с вами некими магическими ES6 подходами по решению распространенных задач по нахождению в JavaScript пересечения массивов, поиск непересекаемых значений массива, или объединение всех элементов.

Эти задачи очень распространенные, но, иногда, мы слишком мудрИм, решая их. В этой статье я поделюсь с вами элегантными решениями, как можно, используя filter и Set решить эти задачи в одну-дву строки кода.

Код

Для всех последующих примеров мы смоделируем общий пример двух массивов, которые будем использовать во всех примерах:

const arrayA = [1, 3, 4, 5];
const arrayB = [1, 2, 5, 6, 7];

А результатом этих операций будет let result. Давайте разберём концепцию каждой задачи на примере Диаграмм Венна, для более ясной визуализации.


Пересечение элементов двух массивов

1_e-oNITnttVBvVa-phu8e9g

Результатом поиска пересечения элементов, которые являются общими для каждого из двух массивов будет [1, 5].

let intersection = arrayA.filter(num => arrayB.includes(num));

Разница между массивами

1_5l_pvAqVSS0UjwmpKKbjZg

В этом примере найдём разницу элементов между двумя массивами. То есть, нам нужно найти элементы, элементы из arrayA, которых нет в arrayB.
Результатом будет [3, 4].

let difference = arrayA.filter(num => !arrayB.includes(num));

Симметричная разница

1_ASL4XHHwmntiXEp_bLGRAQ

В этом случае вы получите массив, содержащий все элементы массива arrayA, которые не содержатся в массиве arrayB, и, наоборот. Проще говоря - неповторяющиеся значение из противоположного массивов.
И результатом будет [2, 3, 4, 6, 7].

let difference = arrayA
     .filter(num => !arrayB.includes(num))
     .concat(arrayB.filter(num => !arrayA.includes(num)));

Объединение массивов

1_9zPXVUP_8KqPh7f2U5ucfQ

Операция слияния, или же, объединения двух массивов является самой простой из всех перечисленных. Результатом будет новый массив со всеми элементами из arrayA и arrayB, и будет выглядеть вот так [1, 2, 3, 4, 5, 6, 7].

let union = [...arrA, ...arrB];

Однако, при таком подходе, когда мы используем Spread-оператор, элементы, встречающиеся в каждом из массивов - дублируются. Потому, это не совсем эталонное слияние. Для получения только уникальных значений при объединении двух массивов, привернем к использованию Set:

let union = [...new Set([...arrayA, ...arrayB])];

Почему Set? Set - это JavaScript структуру, которая хранит только уникальные значения. И, если вы попытаетесь добавить с Set уже существующее значение, то оно будет проигнорировано. Потому, именно благодаря такому свойству мы и добиваемся удаления дубликатов в массиве JavaScript, используя объект Set.


JavaScript шагнул настолько далеко в своём стандартном ES6 функционале, благодаря чему, вы можете отказаться от многих компонентов или библиотек, типа jQuery, lodash, или underscore. И вы можете уменьшить код из такого:

function symmetricDifference(a1, a2) {
  var result = [];
  for (var i = 0; i < a1.length; i++) {
    if (a2.indexOf(a1[i]) === -1) {
      result.push(a1[i]);
    }
  }
  for (i = 0; i < a2.length; i++) {
    if (a1.indexOf(a2[i]) === -1) {
      result.push(a2[i]);
    }
  }
  return result;
}

До одной-двух строк кода, как мы разбирали выше. И это выглядит круто!

1_yjl4_CG_kE5QAjrClnygOw

Так же, дополнительно советую почитать статью по работе с массивами в JavaScript, а так же, работу с объектами и распространёнными задачами, связанными с этими структурами.