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

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

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

Код

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

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

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


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

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

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

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

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

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

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

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

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

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

Операция слияния, или же, объединения двух массивов является самой простой из всех перечисленных. Результатом будет новый массив со всеми элементами из 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;
}

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

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