Источник: Nuances of Programming
Иногда бывает нужно получить все повторяющиеся значения из массива 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 (повторяющихся значений).
Заключение
Для получения из массива повторяющихся значений используются различные методы массивов и объектов. Мы рассмотрели лишь малую их часть.
Читайте также:
Перевод статьи John Au-Yeung: How to Get All Non-Unique Values in a JavaScript Array?