В Javascript, как проверить, имеет ли массив повторяющиеся значения?

Возможный дубликат:
Самый простой способ найти повторяющиеся значения в массиве javascript

Как проверить, имеет ли массив повторяющиеся значения?

Если некоторые элементы в массиве одинаковы, верните true. В противном случае верните false.

['hello','goodbye','hey'] //return false because no duplicates exist
['hello','goodbye','hello'] // return true because duplicates exist

Ответ 1

Если у вас есть среда ES2015 (начиная с этой записи: io.js, IE11, Chrome, Firefox, WebKit в ночное время), то следующее будет работать и будет быстрым (а именно, 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 (n 2) вместо 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.

Ответ 2

Другой подход (также для элементов объекта/массива в массиве 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: теперь может использоваться для простой проверки или для возврата массива повторяющихся значений