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

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

类似的问题:

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


当前回答

还有一种方法是使用下划线。Numbers是源数组,dupes可能有重复的值。

var itemcounts = _.countBy(numbers, function (n) { return n; });
var dupes = _.reduce(itemcounts, function (memo, item, idx) {
    if (item > 1)
        memo.push(idx);
    return memo;
}, []);

其他回答

更新:以下使用一个优化的组合策略。它优化了原语查找,以受益于散列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;
    }
  });
}
var isUnique = true;      
for (var i= 0; i< targetItems.length; i++) {
        var itemValue = $(targetItems[i]).val();
        if (targetListValues.indexOf(itemValue) >= 0) {
          isUnique = false;
           break;
        }
      targetListValues.push(itemValue);
        if (!isUnique) {
          //raise any error msg
          return false;
        }
      }
function GetDuplicates(arr) {
    var i = 0, m = [];
    return arr.filter(function (n) {
        return !m[n] * ~arr.indexOf(n, m[n] = ++i);
    });
}
var a= [1, 2,2,3,3,4,4,4];
var m=[];
var n = [];
a.forEach(function(e) {
  if(m.indexOf(e)=== -1) {
    m.push(e);
}else if(n.indexOf(e)=== -1){
    n.push(e);
}

});

您可以对数组进行排序,然后遍历它,然后查看下一个(或上一个)索引是否与当前索引相同。假设你的排序算法是好的,这个应该小于O(n2):

const findDuplicates = (arr) => { let sorted_arr = arr.slice().sort(); // You can define the comparing function here. // JS by default uses a crappy string compare. // (we use slice to clone the array so the // original array won't be modified) let results = []; for (let i = 0; i < sorted_arr.length - 1; i++) { if (sorted_arr[i + 1] == sorted_arr[i]) { results.push(sorted_arr[i]); } } return results; } let duplicatedArray = [9, 9, 111, 2, 3, 4, 4, 5, 7]; console.log(`The duplicates in ${duplicatedArray} are ${findDuplicates(duplicatedArray)}`);

在这种情况下,如果你要返回一个重复的函数。这是为类似类型的情况。

参考:https://stackoverflow.com/a/57532964/8119511