В Javascript, как я могу проверить, если массив имеет повторяющиеся значения?
Возможный дубликат:
Самый простой способ найти повторяющиеся значения в массиве JavaScript
Как проверить, есть ли в массиве повторяющиеся значения?
Если некоторые элементы в массиве совпадают, вернуть true. В противном случае верните false.
['hello','goodbye','hey'] //return false because no duplicates exist
['hello','goodbye','hello'] // return true because duplicates exist
12 ответов
Если у вас есть среда ES2015 (на момент написания статьи: io.js, IE11, Chrome, Firefox, WebKit nightly), то будет работать следующее и будет быстро (а именно O(n)):
function hasDuplicates(array) {
return (new Set(array)).size !== array.length;
}
Если вам нужны только строковые значения в массиве, будет работать следующее:
function hasDuplicates(array) {
var valuesSoFar = Object.create(null);
for (var i = 0; i < array.length; ++i) {
var value = array[i];
if (value in valuesSoFar) {
return true;
}
valuesSoFar[value] = true;
}
return false;
}
Мы используем "хэш-таблицу" valuesSoFar
ключи которого являются значениями, которые мы видели в массиве до сих пор. Мы делаем поиск, используя in
чтобы увидеть, было ли это значение уже обнаружено; если это так, мы выходим из цикла и возвращаемся true
,
Если вам нужна функция, которая работает не только для строковых значений, то сработает следующее, но не так эффективно; это O (n2) вместо O(n).
function hasDuplicates(array) {
var valuesSoFar = [];
for (var i = 0; i < array.length; ++i) {
var value = array[i];
if (valuesSoFar.indexOf(value) !== -1) {
return true;
}
valuesSoFar.push(value);
}
return false;
}
Разница в том, что мы используем массив вместо хеш-таблицы для valuesSoFar
Так как JavaScript "хеш-таблицы" (т.е. объекты) имеют только строковые ключи. Это означает, что мы теряем время поиска O(1) in
вместо того, чтобы получить O (N) время поиска indexOf
,
Вы можете использовать SET для удаления дубликатов и сравнения. Если вы скопируете массив в набор, он удалит все дубликаты. Затем просто сравните длину массива с размером набора.
function hasDuplicates(a) {
const noDups = new Set(a);
if (a.length !== noDups.size) {
return true;
} else {
return false;
}
}
Другой подход (также для элементов объекта / массива в массиве1) может быть2:
function chkDuplicates(arr,justCheck){
var len = arr.length, tmp = {}, arrtmp = arr.slice(), dupes = [];
arrtmp.sort();
while(len--){
var val = arrtmp[len];
if (/nul|nan|infini/i.test(String(val))){
val = String(val);
}
if (tmp[JSON.stringify(val)]){
if (justCheck) {return true;}
dupes.push(val);
}
tmp[JSON.stringify(val)] = true;
}
return justCheck ? false : dupes.length ? dupes : null;
}
//usages
chkDuplicates([1,2,3,4,5],true); //=> false
chkDuplicates([1,2,3,4,5,9,10,5,1,2],true); //=> true
chkDuplicates([{a:1,b:2},1,2,3,4,{a:1,b:2},[1,2,3]],true); //=> true
chkDuplicates([null,1,2,3,4,{a:1,b:2},NaN],true); //=> false
chkDuplicates([1,2,3,4,5,1,2]); //=> [1,2]
chkDuplicates([1,2,3,4,5]); //=> null
1 нужен браузер с поддержкой JSON или библиотека JSON, если нет.
2 edit: функция теперь может использоваться для простой проверки или для возврата массива повторяющихся значений.
Если вы имеете дело с простыми значениями, вы можете использовать
array.some()
а также
indexOf()
например, скажем
vals
является
["b", "a", "a", "c"]
const allUnique = !vals.some((v, i) => vals.indexOf(v) < i);
some()
вернет истину, если какое-либо выражение вернет истину. Здесь мы перебираем значения (из индекса 0) и вызываем indexOf(), который вернет индекс первого вхождения данного элемента (или -1, если не в массиве). Если его идентификатор меньше текущего, перед ним должно быть хотя бы одно такое же значение. таким образом, итерация 3 вернет истину, поскольку "a" (с индексом 2) сначала будет найдено по индексу 1.
Вы можете воспользоваться
indexOf
а также
lastIndexOf
. если оба индекса не совпадают, у вас есть дубликат.
function containsDuplicates(a) {
for (let i = 0; i < a.length; i++) {
if (a.indexOf(a[i]) !== a.lastIndexOf(a[i])) {
return true
}
}
return false
}
просто, вы можете использовать
Array.prototype.every
функция
function isUnique(arr) {
const isAllUniqueItems = input.every((value, index, arr) => {
return arr.indexOf(value) === index; //check if any duplicate value is in other index
});
return isAllUniqueItems;
}
Зачем использовать этот метод:
Я думаю, что это лучший способ сделать это при работе с несколькими массивами и циклами. Этот пример очень прост, но в некоторых случаях, например, при итерации с несколькими циклами и переборе объектов, это наиболее надежный и оптимальный способ сделать это.
Объяснение:
В этом примере массив повторяется, элемент такой же, как array[i] i — это позиция массива, в котором в данный момент находится цикл, затем функция проверяет позицию в читаемом массиве, который инициализируется как пустой, если элемент не находится в массиве чтения, он вернет -1 и будет помещен в массив чтения, в противном случае он вернет свою позицию и не будет отправлен, как только весь элемент массива будет повторен, массив чтения будет быть напечатано на консоли
Одна приятная вещь о решениях, которые используют
Set
является
O(1)
производительность при поиске существующих элементов в списке, вместо того, чтобы зацикливаться на нем.
Одна приятная вещь о решениях, которые используют
Some
замыкает, когда дубликат обнаруживается раньше, поэтому вам не нужно продолжать оценку остальной части массива, когда условие уже выполнено.
Одно из решений, которое сочетает в себе оба, состоит в том, чтобы постепенно создавать набор, досрочно завершать работу, если текущий элемент существует в наборе, в противном случае добавлять его и переходить к следующему элементу.
Согласно JSBench.me , должно быть достаточно хорошо для различных вариантов использования. Подход с заданным размером является самым быстрым без дубликатов, а проверка некоторых + indexOf является самой неудачной с очень ранним дублированием, но это решение хорошо работает в обоих сценариях, что делает его хорошей универсальной реализацией.
this.selectedExam = [];
// example exam obj: {examId:1, name:'ExamName'}
onExamSelect(exam: any) {
if(!this.selectedExam.includes(exam?.name)){
this.selectedExam.push(exam?.name);
}}
В приведенном выше коде я взял массив, и при запуске определенной функции (onExamSelect) мы проверяем дубликаты и помещаем уникальные элементы.
function hasAllUniqueChars( s ){
for(let c=0; c<s.length; c++){
for(let d=c+1; d<s.length; d++){
if((s[c]==s[d])){
return false;
}
}
}
return true;
}
Ну, я немного искал в интернете для вас, и я нашел эту удобную ссылку.
Самый простой способ найти повторяющиеся значения в массиве JavaScript
Вы можете адаптировать пример кода, который приведен в приведенной выше ссылке, любезно предоставленного "swilliams", к вашему решению.