Иногда бывает нужно получить все повторяющиеся значения из массива JavaScript.

В этой статье мы рассмотрим способы получения всех неуникальных значений в массиве JavaScript.

Array.prototype.filter

Один из таких способов связан с использованием метода filter массива JavaScript для возвращения массива, соответствующего заданному условию.

Он принимает функцию обратного вызова, возвращающую условие, которое должно быть у каждого возвращаемого элемента.

Задействуя метод filter вместе с вызовом метода indexOf в функции обратного вызова, мы проверяем, является ли встреченный элемент первым.

Для этого в массиве, в котором вызывается filter, вызываем indexOf, получаемый из третьего параметра функции обратного вызова.

Затем проверяем, совпадает ли возвращаемый индекс с тем, которому соответствует итерируемый элемент.

Например, напишем следующее:

const duplicates = [1, 2, 2, 4, 3, 4].filter((e, index, arr) => arr.indexOf(e) !== index)
console.log(duplicates)

Затем вызываем filter с функцией обратного вызова, которая принимает параметры e, index и arr, где:

  • e  —  это элемент, по которому выполняется итеративный обход;
  • index  —  это индекс элемента e;
  • arr  —  это массив, в котором вызывается filter.

Мы вызываем indexOf в arr с аргументом e, чтобы вернуть индекс первого встреченного элемента e в массиве arr.

Несовпадение ​возвращаемого индекса с index свидетельствует о том, что это встреченное значение не первое.

Следовательно, duplicates (повторяющиеся значения)  —  это [2, 4], так как они дублируются в массиве.

Подсчет элементов

Посчитаем элементы в массиве, создав собственный объект для задания значения счетчика:

const obj = [1, 2, 2, 4, 3, 4]
  .map((val) => {
    return {
      count: 1,
      val
    }
  })
  .reduce((a, b) => {
    a[b.val] = (a[b.val] || 0) + b.count
    return a
  }, {})const duplicates = Object.entries(obj)
  .filter(([, val]) => {
    return val > 1
  })
  .map(([key]) => +key)
console.log(duplicates)

Вызываем map для сопоставления каждой записи объекту со счетчиком count, имеющим значение 1, и со значением элемента массива val.

Затем вызываем reduce для создания объекта со счетчиком каждого элемента, где каждый элемент будет ключом.

Делаем это, присваивая счетчик из a[b.val] с (a[b.val] || 0) + b.count.

В b.count имеется новый счетчик.

И возвращаем a, где содержатся все произведенные подсчеты.

Второй аргумент  —  пустой объект, поэтому создаем объект в конце.

Затем для получения повторяющихся значений мы берем все ключи со значением больше 1.

Для этого вызываем Object.entries в obj.

После чего вызываем filter с функцией обратного вызова для возвращения любых записей со значением val больше 1.

val  —  это значение свойства объекта.

Затем вызываем map для получения ключа key из массивов, содержащих пары «ключ-значение».

Получаем тот же результат, что и в предыдущем примере для duplicates (повторяющихся значений).

Заключение

Для получения из массива повторяющихся значений используются различные методы массивов и объектов. Мы рассмотрели лишь малую их часть.

Читайте также:

Читайте нас в Telegram, VK и Яндекс.Дзен


Перевод статьи John Au-Yeung: How to Get All Non-Unique Values in a JavaScript Array?

Предыдущая статья3 способа локального хранения и чтения учетных данных в Python
Следующая статьяЭтические аспекты клонирования голоса и возможности его применения