- 1 Методы filter() и indexOf()
- 2 Использование объекта set и метода has()
- 3 Использование метода some() для выявления дубликатов в массиве
- 4 Удалить одинаковые элементы в массиве JS при помощи объектов и ключей
- 5 Поиск повторений вручную через вложенный цикл for
- 6 Как удалить одинаковые элементы в массиве JS с помощью циклов
- 7 Сортировка с помощью цикла for для поиска дубликатов
- 8 Кроссбраузерность
В этой статье мы рассмотрим различные способы найти и удалить одинаковые элементы в массиве в (JS) JavaScript. Речь идёт о различных встроенных методах и некоторых самописных вариантах поиска текущего количества дубликатов (с использованием циклов).
Мы рассмотрим:
- Определение того, содержит ли массив одинаковые элементы.
- Получение массива повторяющихся элементов.
- Фильтрацию повторяющихся элементов для получения массива уникальных элементов.
Методы filter() и indexOf()
Один из самых простых и эффективных способов отфильтровать массив и удалить его дубликаты — использовать метод filter совместно с indexOf.
Давайте рассмотрим различные способы использования этой комбинации.
Удаление дубликатов с помощью метода filter
Он может использоваться для фильтрации массива на основе заданного условия. Этот метод вернёт новый массив, которым можно заменить исходный, или присвоить новой переменной.
В ходе выполнения итераций по всему массиву на каждой из них filter получает доступ к текущему элементу и его индексу (необязательно). Можно сохранить эти значения во временных переменных (в нашем примере мы использовали «a» для текущего значения и «i» для индекса). Затем вы можно задать условие, которое будет проверяться при каждой итерации.
В нашем примере мы проверяем, совпадает ли индекс элемента «a» с индексом «i», используя метод indexOf. Этот метод возвращает индекс первого совпадения данного элемента.
Итак, если индексы совпадают, то это означает, что это первый или, возможно, единственный подобный элемент в массиве. Если нет, значит, имеется его дубликат, который не будет учитываться при фильтрации.
В конце мы получим только уникальные элементы, а дублированные будут проигнорированы, как показано ниже.
let arr = [1,2,1,4,3,2,5,3,6,4];
arr = arr.filter((a,i) => arr.indexOf(a) == i);
console.log(arr); // [1, 2, 4, 3, 5, 6]
Поиск дубликатов с помощью метода filter
Можно немного изменить условие фильтрации, чтобы получить массив дубликатов. Достаточно просто найти экземпляры, где первый индекс (первое вхождение) «a» (текущего элемента) не совпадает с текущим. Это означает, что мы имеем дело с дубликатами, как показано ниже.
arr = arr.filter((a,i) => arr.indexOf(a) !== i); // [1, 2, 3, 4]
Использование объекта set и метода has()
Объект set — отличный способ отфильтровать массив на наличие дубликатов. Почему? По умолчанию он может включать только уникальные элементы.
Преобразуя массив в set происходит автоматическое удаление повторяющихся элементов. Теперь давайте рассмотрим различные способы использования такого подхода для их поиска и удаления в массиве.
Удалить одинаковые элементы в массиве JS с помощью set
Самый простой способ удалить дубликаты в вашем массиве — это сначала преобразовать его в set с использованием синтаксиса new Set(arr).
Затем следует использовать метод Array.from(), чтобы преобразовать этот уникальный набор обратно в массив и присвоить его в новую переменную (или ту же самую, если необходимо изменить исходный массив).
let arr = [1,2,1,4,3,2,5,3,6,4];
let uniqueArr = Array.from(new Set(arr));
// Удаление повторяющихся элементов
console.log(uniqueArr); [1, 2, 4, 3, 5, 6]
Проверка массива на дубликаты при помощи set
После преобразования массива в set и обратно в уникальный массив, как мы делали выше, можно сравнить вновь созданный массив с исходным. Это позволит проверить массив на наличие дубликатов.
Самый простой способ выполнить это сравнение — использовать свойство length. Если оба массива имеют одинаковую длину (одинаковое количество элементов), дубликатов нет.
// Проверка исходного массива на дубликаты элементов
if(arr.length === uniqueArr.length) {
console.log('В массиве нет повторений');
}
else {
console.log('В массиве есть повторения');
}
Как выявить одинаковые элементы в массиве JS методами set object и has
Ранее мы рассматривали фильтрацию массива дубликатов с помощью set и выявление повторяющихся элементов.
Что делать, если необходимо выяснить, что это за дубликаты?
Для этого требуется:
- Создать пустой массив duplicates, как обычно.
- Преобразовать исходный массив в set и сохраните его как есть (не преобразовывая его обратно в array).
- Перебрать циклом исходный массив. Для каждой итерации использовать метод has, чтобы проверить, существует ли текущий элемент в наборе.
- Удаление элемента из set методом delete.
let uniqueSet = new Set(arr); // Сразу получаем только элементы с уникальными значениями
let duplicates = [];
// Фильтруем массив и удаляем все уникальные значения из набора, чтобы остались только дубликаты
arr.forEach((a) => {
if(uniqueSet.has(a)) {
uniqueSet.delete(a);
}
else {
duplicates.push(a);
}
});
console.log(duplicates); // [1, 2, 3, 4]
Далее следует предпринять:
- Если значение не существует в set, это означает, что оно было удалено на предыдущей итерации, и мы столкнулись с дубликатом.
- Перемещение этого значение в массив duplicates. Как обычно, также можно проверить, существует ли значение уже в массиве duplicates.
Поиск дубликатов и получение уникального массива одновременно
До сих пор мы использовали несколько способов манипулирования или использования объектов set для поиска / удаления дубликатов из массива. Давайте объединим то, что мы рассмотрели, в один фрагмент кода.
let set = new Set();
let duplicates = [];
arr.forEach((a) => {
if(set.has(a)) {
// Если значение элемента повторяется
duplicates.push(a);
}
else {
set.add(a);
}
});
console.log(duplicates); // [1, 2, 3, 4]
console.log(Array.from(set)); // [1, 2, 4, 3, 5, 6]
В коде выше совершаются следующие действия:
- Мы создали пустой набор и массив. Пустой набор будет хранить уникальные значения, а массив duplicates — использоваться для хранения значений, которые были продублированы.
- Далее выполним цикл по исходному массиву. На каждой итерации проведём проверку, есть ли уже текущий элемент массива в наборе.
- Если это так, то мы столкнулись с дубликатом, поэтому это значение элемента переносится в массив duplicates. В качестве альтернативы можно проверить, существует ли значение уже и в массиве duplicates (повторяется более 3 раз).
- Если такого элемента ещё нет в set, добавим ему значение, используя метод add.
Использование метода some() для выявления дубликатов в массиве
Метод some может использоваться для возврата значений true или false в зависимости от заданного условия. Точно так же, как метод filter, some также выполняет итерации по заданному массиву, и для каждой итерации можно осуществлять проверку указанных условий. Если условие возвращает false даже для одной (или более) итерации, весь метод some вернёт true. В противном случае результатом будет false.
let arr = [1,2,1,4,3,2,5,3,6,4];
let duplicates = arr.some((a,i) => {
return arr.indexOf(a) !== i
});
if(duplicates) {
console.log('В массиве присутствуют повторения')
}
else {
console.log('В массиве отсутствуют повторения');
}
Как вы можете видеть выше, мы задали то же условие, которое использовали в методе filter. На каждой итерации мы проверяем, не совпадает ли индекс элемента «a» с текущим индексом «i». Если это условие возвращает true хотя бы один раз, то это означает, что в нашем массиве есть дубликаты. Наконец, мы используем оператор if else для получения результатов.
К сожалению, этот метод можно использовать только для определения того, есть ли в нашем массиве дубликаты. Чтобы удалить дубликаты или определить, что это за повторяющиеся элементы, вам нужно воспользоваться другими методами, упомянутыми в этой статье.
Удалить одинаковые элементы в массиве JS при помощи объектов и ключей
Также можно использовать объекты и их пары свойство-значение, чтобы определить, присутствуют ли в массиве дубликаты.
let obj = {};
let duplicates = [];
arr.forEach((a) => {
if(!obj[a]) {
obj[a] = true; // Создаём новую пару свойства-значения для элемента
}
else {
// Внесение дубликата в массив
duplicates.push(a);
}
});
console.log(duplicates); // [1, 2, 3, 4]
Во фрагменте кода выше были реализованы следующие шаги:
- Для начала мы создали пустой объект obj и пустой массив duplicates.
- Затем мы запустили цикл forEach для исходного массива. На каждой итерации присваиваем текущий элемент массива временной переменной «a».
- Затем для каждой итерации мы используем оператор if else, чтобы отфильтровать повторяющиеся элементы.
- Если obj[a] имеет значение false, например, если «a» ещё не является свойством объекта obj, то это означает, что мы впервые сталкиваемся с этим элементом. Далее необходимо создать свойство «a» в объекте и присвоить ему значение true.
- Если нет, то это означает, что это свойство уже имеется в объекте. Здесь мы имеем дело с дубликатом.
- Далее перемещаем этот элемент в массив duplicates.
- Кроме того, можно проверить, содержит ли массив duplicates уже этот элемент. В случае, если элемент повторяется, следует использовать метод includes. Таким образом, мы получим только одно вхождение каждого дублированного значения в массив duplicates.
Поиск повторений вручную через вложенный цикл for
Также можно вручную удалить дубликаты, чтобы получить массив только с уникальными элементами. Для этого потребуется вложенный цикл for.
let arr = [1,2,1,4,3,2,5,3,6,4];
let isDuplicate = false;
for(let i = 0; i < arr.length; i++) {
for(let j = i+1; j < arr.length; j++) {
if(arr[i] === arr[j]) {
isDuplicate = true;
break;
}
}
if(isDuplicate === true) break;
}
Для реализации этого способа следует:
- Создать переменную isDuplicate и присвоить ей начальное значение false.
- Прописать вложенный цикл for. Внешний цикл выполняется от 0 до length -1, где length — количество элементов в исходном массиве.
- Внутренний цикл выполняется от i + 1 до length -1. Таким образом, текущий элемент можно сравнить с следующим элементом (i +1).
- Если arr[i] и arr[j] одинаковы (означает, что мы столкнулись с дубликатом), isDuplicate получает значение true.
- Для прерывания цикла используется оператор break.
- Если значение isDuplicate равно true, то проверка завершена. Итак, перед выполнением следующей итерации внешнего цикла проверьте, равно ли значение true. Если это так, то надо выйти из внешнего цикла и получить результаты в нужном виде.
Как найти одинаковые элементы в массиве JS
Если вы хотите найти повторяющиеся значения с помощью вложенного цикла, то немного измените строки кода внутри внутреннего цикла for.
let duplicates = [];
for(let i = 0; i < arr.length; i++) {
for(let j = i+1; j < arr.length; j++) {
if(arr[i] === arr[j]) {
if(!duplicates.includes(arr[i])) {
duplicates.push(arr[i]);
}
}
}
}
console.log(duplicates); // [1, 2, 4, 3]
Как вы можете видеть, на каждой итерации внутреннего цикла мы проверяем, совпадают ли arr[i] и arr[j]. Если это имеет место быть, то мы столкнулись с повторяющимся значением. В этом случае мы используем метод includes, чтобы проверить, имеет ли уже массив duplicates значение arr[i]. Если нет, то мы сохраняем это значение в массиве.
Таким образом, даже если значение дублируется более двух раз, достаточно всего одной его копии в duplicates. Наконец, мы можем вывести массив duplicates для отображения списка дублированных значений.
Как удалить одинаковые элементы в массиве JS с помощью циклов
Как ещё можно удалить повторяющиеся элементы на JS из массива? Нужно создать новый массив (uniqueArr), в котором будут храниться уникальные значения.
Для каждой итерации цикла for проверяем, существует ли уже значение arr[i] в uniqueArr. Если это не так, помещаем его в uniqueArr. Таким образом, будут отобраны только элементы с уникальными значениями.
let uniqueArr = [];
for(let i = 0; i < arr.length; i++) {
if(!uniqueArr.includes(arr[i])) {
uniqueArr.push(arr[i]);
}
}
console.log(uniqueArr); //[1, 2, 4, 3, 5, 6]
arr.forEach(a => {
if(!uniqueArr.includes(a)) {
uniqueArr.push(a);
}
});
Читайте также: Деструктуризация объектов в JavaScript.
Сортировка с помощью цикла for для поиска дубликатов
Ещё один простой способ найти дубликаты в массиве —использовать метод sort. Примените этот метод к начальному массиву, чтобы отсортировать значения в порядке возрастания.
Затем можно выполнить цикл по отсортированному массиву. В случае наличия дубликатов текущее значение и значение рядом должны совпадать в определённый момент.
let arr = [1,2,1,4,3,2,5,3,6,4];
arr.sort();
console.log(arr); // [1, 1, 2, 2, 3, 3, 4, 4, 5, 6]
let duplicates = [];
for(let i = 0; i < arr.length; i++) {
if(arr[i] === arr[i+1] && !duplicates.includes(arr[i])) {
duplicates.push(arr[i]);
}
}
console.log(duplicates); // [1, 2, 3, 4]
Если это так, и если значение ещё не существует в массиве duplicates, надо переместить его в массив duplicates. Это позволит убедиться, что мы не сохраняем элемент с одинаковым значением дважды.
Кроссбраузерность
Стоит отметить, что все рассмотренные в этой статье методы имеют полную поддержку браузерами за исключением Array.from(), который не воспринимается Internet Explorer.