我需要检查一个JavaScript数组,看看是否有任何重复的值。最简单的方法是什么?我只需要找到复制的值是什么——实际上我不需要它们的索引,也不需要它们复制了多少次。

我知道我可以循环遍历数组并检查所有其他值是否匹配,但似乎应该有更简单的方法。

类似的问题:

获取JavaScript数组中所有唯一的值(删除重复值)


当前回答

排名较高的答案有一些固有的问题,包括使用遗留的javascript,不正确的排序或只支持2个重复的项目。

这里有一个解决这些问题的现代解决方案:

const arrayNonUniq = array => {
    if (!Array.isArray(array)) {
        throw new TypeError("An array must be provided!")
    }

    return array.filter((value, index) => array.indexOf(value) === index && array.lastIndexOf(value) !== index)
}

arrayNonUniq([1, 1, 2, 3, 3])
//=> [1, 3]

arrayNonUniq(["foo", "foo", "bar", "foo"])
//=> ['foo']

你也可以使用npm包array-non-uniq。

其他回答

更新:以下使用一个优化的组合策略。它优化了原语查找,以受益于散列O(1)查找时间(在原语数组上惟一地运行是O(n))。对象查找通过在遍历对象时用唯一id标记对象来优化,因此识别重复对象也是每个项目O(1),整个列表O(n)。唯一的例外是被冻结的项目,但这种情况很少见,并且使用数组和indexOf提供了一个回退。

var unique = function(){
  var hasOwn = {}.hasOwnProperty,
      toString = {}.toString,
      uids = {};

  function uid(){
    var key = Math.random().toString(36).slice(2);
    return key in uids ? uid() : uids[key] = key;
  }

  function unique(array){
    var strings = {}, numbers = {}, others = {},
        tagged = [], failed = [],
        count = 0, i = array.length,
        item, type;

    var id = uid();

    while (i--) {
      item = array[i];
      type = typeof item;
      if (item == null || type !== 'object' && type !== 'function') {
        // primitive
        switch (type) {
          case 'string': strings[item] = true; break;
          case 'number': numbers[item] = true; break;
          default: others[item] = item; break;
        }
      } else {
        // object
        if (!hasOwn.call(item, id)) {
          try {
            item[id] = true;
            tagged[count++] = item;
          } catch (e){
            if (failed.indexOf(item) === -1)
              failed[failed.length] = item;
          }
        }
      }
    }

    // remove the tags
    while (count--)
      delete tagged[count][id];

    tagged = tagged.concat(failed);
    count = tagged.length;

    // append primitives to results
    for (i in strings)
      if (hasOwn.call(strings, i))
        tagged[count++] = i;

    for (i in numbers)
      if (hasOwn.call(numbers, i))
        tagged[count++] = +i;

    for (i in others)
      if (hasOwn.call(others, i))
        tagged[count++] = others[i];

    return tagged;
  }

  return unique;
}();

如果你有ES6集合可用,那么有一个更简单、更快的版本。(shim适用于IE9+和其他浏览器:https://github.com/Benvie/ES6-Harmony-Collections-Shim)

function unique(array){
  var seen = new Set;
  return array.filter(function(item){
    if (!seen.has(item)) {
      seen.add(item);
      return true;
    }
  });
}

这也可以使用Set()来解决。

Set中的一个值只能出现一次;在Set的收藏中是独一无二的。

    Array.prototype.hasDuplicates = function () {
        if (arr.length !== (new Set(arr).size)) {
            return true;
        }
        return false;
    }

更多关于集合的信息: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set

注意:IE中不完全支持集合。

这应该能得到你想要的,只是副本。

function find_duplicates(arr) {
  var len=arr.length,
      out=[],
      counts={};

  for (var i=0;i<len;i++) {
    var item = arr[i];
    counts[item] = counts[item] >= 1 ? counts[item] + 1 : 1;
    if (counts[item] === 2) {
      out.push(item);
    }
  }

  return out;
}

find_duplicates(['one',2,3,4,4,4,5,6,7,7,7,'pig','one']); // -> ['one',4,7] in no particular order.

Var arr = [2,1,2,2,4,4,2,5]; 函数returnduplicate (arr) { 加勒比海盗。Reduce(函数(dupes, val, i) { 如果(arr.indexOf (val) ! = =我& & dupes.indexOf (val) = = = 1) { dupes.push (val); } 返回欺骗; },[]); } alert (returnDuplicates (arr));

这个函数避免了排序步骤,并使用reduce()方法将重复项推入一个新数组(如果该数组中不存在)。

这是用ES6语法找到重复元素的最简单方法

Const arr =[1,2,3,3,21,3, 21,34] const duplicate = Array.from(new Set(arr. from)filter((例如,i, ar)=> i !==ar. indexof(例如)))) console.log(副本)