关于javascript:获取数组中的所有非唯一值(即:复制/多次出现)

Get all non-unique values (i.e.: duplicate/more than one occurrence) in an array

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

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

类似问题:

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


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

1
2
3
4
5
6
7
8
9
10
11
12
13
var arr = [9, 9, 111, 2, 3, 4, 4, 5, 7];
var 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)
var results = [];
for (var i = 0; i < sorted_arr.length - 1; i++) {
    if (sorted_arr[i + 1] == sorted_arr[i]) {
        results.push(sorted_arr[i]);
    }
}

console.log(results);


如果您想删除重复项,请尝试以下伟大的解决方案:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function eliminateDuplicates(arr) {
  var i,
      len = arr.length,
      out = [],
      obj = {};

  for (i = 0; i < len; i++) {
    obj[arr[i]] = 0;
  }
  for (i in obj) {
    out.push(i);
  }
  return out;
}

来源:http://dreaminginjavascript.wordpress.com/2008/08/22/eliming-duplicates/


这是我从重复的线程中得到的答案!!):

编写此条目2014时-所有示例都是针对循环或jquery的。Javascript拥有完美的工具:排序、映射和减少。

查找重复项

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var names = ['Mike', 'Matt', 'Nancy', 'Adam', 'Jenny', 'Nancy', 'Carl']

var uniq = names
  .map((name) => {
    return {
      count: 1,
      name: name
    }
  })
  .reduce((a, b) => {
    a[b.name] = (a[b.name] || 0) + b.count
    return a
  }, {})

var duplicates = Object.keys(uniq).filter((a) => uniq[a] > 1)

console.log(duplicates) // [ 'Nancy' ]

更多功能语法:

@Dmytro Laptin指出了一些需要删除的代码。这是同一代码的更紧凑的版本。使用一些ES6技巧和高阶函数:

1
2
3
4
5
6
7
8
9
10
11
12
const names = ['Mike', 'Matt', 'Nancy', 'Adam', 'Jenny', 'Nancy', 'Carl']

const count = names =>
  names.reduce((a, b) => ({ ...a,
    [b]: (a[b] || 0) + 1
  }), {}) // don't forget to initialize the accumulator

const duplicates = dict =>
  Object.keys(dict).filter((a) => dict[a] > 1)

console.log(count(names)) // { Mike: 1, Matt: 1, Nancy: 2, Adam: 1, Jenny: 1, Carl: 1 }
console.log(duplicates(count(names))) // [ 'Nancy' ]


在数组中查找重复值

这应该是在数组中实际查找重复值的最短方法之一。正如OP特别要求的那样,这不会删除重复项,但会找到它们。

1
2
3
4
5
6
7
var input = [1, 2, 3, 1, 3, 1];

var duplicates = input.reduce(function(acc, el, i, arr) {
  if (arr.indexOf(el) !== i && acc.indexOf(el) < 0) acc.push(el); return acc;
}, []);

document.write(duplicates); // = 1,3 (actual array == [1, 3])

这不需要排序或任何第三方框架。它也不需要手动循环。它适用于每个indexof()值(或者更清晰:严格的比较运算符)支持。

由于reduce()和indexof(),它至少需要IE 9。


您可以添加此函数,或者调整它并将其添加到javascript的数组原型中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Array.prototype.unique = function () {
    var r = new Array();
    o:for(var i = 0, n = this.length; i < n; i++)
    {
        for(var x = 0, y = r.length; x < y; x++)
        {
            if(r[x]==this[i])
            {
                alert('this is a DUPE!');
                continue o;
            }
        }
        r[r.length] = this[i];
    }
    return r;
}

var arr = [1,2,2,3,3,4,5,6,2,3,7,8,5,9];
var unique = arr.unique();
alert(unique);


更新:以下使用了优化的组合策略。它优化了基元查找以从哈希O(1)查找时间(在基元数组上运行unique是O(n))中获益。对象查找是通过在迭代过程中用唯一的ID标记对象来优化的,因此识别重复对象也是每个项目的O(1)和整个列表的O(n)。唯一的例外是冻结的项,但这些项很少,并且使用数组和indexof提供回退。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
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集合可用,那么有一个更简单、速度显著更快的版本。(适用于IE9+和其他浏览器的垫片:https://github.com/benvie/es6-harmony-collections-shim)

1
2
3
4
5
6
7
8
9
function unique(array){
  var seen = new Set;
  return array.filter(function(item){
    if (!seen.has(item)) {
      seen.add(item);
      return true;
    }
  });
}


这应该能让你得到你想要的,只是复制品。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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.


1
2
3
var a = ["a","a","b","c","c"];

a.filter(function(value,index,self){ return (self.indexOf(value) !== index )})


使用下划线.js

1
2
3
function hasDuplicate(arr){
    return (arr.length != _.uniq(arr).length);
}

这是我的简单的单线解决方案。

它首先搜索不唯一的元素,然后使用set使find数组唯一。

所以最后我们有一个重复的数组。

1
2
3
4
5
var array = [1, 2, 2, 3, 3, 4, 5, 6, 2, 3, 7, 8, 5, 22, 1, 2, 511, 12, 50, 22];

console.log([...new Set(
  array.filter((value, index, self) => self.indexOf(value) !== index))]
);


当您只需要检查本问题中是否有重复项时,可以使用every()方法:

1
2
3
[1, 2, 3].every(function(elem, i, array){return array.lastIndexOf(elem) === i}) // true

[1, 2, 1].every(function(elem, i, array){return array.lastIndexOf(elem) === i}) // false

请注意,every()不适用于ie 8及以下版本。

我使用lastIndexOf(),因为如果按索引顺序进行every()所做的函数回调,那么它可能比indexOf()更有效,但这还没有得到证实。

在咖啡描述中,我使用这个:

1
2
3
4
Array::duplicates = -> not @every((elem, i, array) -> array.lastIndexOf(elem) is i)

[1, 2, 3].duplicates() // false
[1, 2, 1].duplicates() // true


1
2
var a = [324,3,32,5,52,2100,1,20,2,3,3,2,2,2,1,1,1].sort();
a.filter(function(v,i,o){return i&&v!==o[i-1]?v:0;});

或者添加到数组的prototyp.chain中时

1
2
3
//copy and paste: without error handling
Array.prototype.unique =
   function(){return this.sort().filter(function(v,i,o){return i&&v!==o[i-1]?v:0;});}

请参见:https://gist.github.com/1305056


从3个数组(或更多)中查找唯一值:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Array.prototype.unique = function () {
    var arr = this.sort(), i; // input must be sorted for this to work
    for( i=arr.length; i--; )
      arr[i] === arr[i-1] && arr.splice(i,1); // remove duplicate item

    return arr;
}

var arr =  [1,2,2,3,3,4,5,6,2,3,7,8,5,9],
    arr2 = [1,2,511,12,50],
    arr3 = [22],
    unique = arr.concat(arr2, arr3).unique();

console.log(unique);  // [22, 50, 12, 511, 2, 1, 9, 5, 8, 7, 3, 6, 4]

对于旧浏览器,只需要数组indexof的polyfill:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
if (!Array.prototype.indexOf){
   Array.prototype.indexOf = function(elt /*, from*/){
     var len = this.length >>> 0;

     var from = Number(arguments[1]) || 0;
     from = (from < 0) ? Math.ceil(from) : Math.floor(from);
     if (from < 0)
        from += len;

     for (; from < len; from++){
        if (from in this && this[from] === elt)
           return from;
     }
     return -1;
  };
}

使用"inarray"的jquery解决方案:

1
if( $.inArray(this[i], arr) == -1 )

ES2015

1
2
3
4
5
6
7
8
9
10
11
12
13
var arr =  [1,2,2,3,3,4,5,6,2,3,7,8,5,22],
    arr2 = [1,2,511,12,50],
    arr3 = [22],
    unique;

// Combine all the arrays to a single one
unique = arr.concat(arr2, arr3);
// create a new (dirty) Array with only the unique items
unique = unique.map((item,i) => unique.includes(item, i+1) ? item : '' )
// Cleanup - remove duplicate & empty items items
unique = [...new Set(unique)].filter(n => n);

console.log(unique);

而不是添加"array.prototype.indexof"


这是我的建议(ES6):

1
2
3
4
let a = [1, 2, 3, 4, 2, 2, 4, 1, 5, 6]
let b = [...new Set(a.sort().filter((o, i) => o !== undefined && a[i + 1] !== undefined && o === a[i + 1]))]

// b is now [1, 2, 4]


使用ES6对象的快速优雅的销毁和减少方法

它在o(n)中运行(对数组进行1次迭代),并且不会重复出现超过2次的值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const arr = ['hi', 'hi', 'hi', 'bye', 'bye', 'asd']
const {
  dup
} = arr.reduce(
  (acc, curr) => {
    acc.items[curr] = acc.items[curr] ? acc.items[curr] += 1 : 1
    if (acc.items[curr] === 2) acc.dup.push(curr)
    return acc
  }, {
    items: {},
    dup: []
  },
)

console.log(dup)
// ['hi', 'bye']


使用ES6(或使用babel或typescipt),您只需执行以下操作:

1
var duplicates = myArray.filter(i => myArray.filter(ii => ii === i).length > 1);

网址:https://es6console.com/j58euhbt/


带有ES6语法的简单代码(返回重复的排序数组):

1
let duplicates = a => {d=[]; a.sort((a,b) => a-b).reduce((a,b)=>{a==b&&!d.includes(a)&&d.push(a); return b}); return d};

如何使用:

1
duplicates([1,2,3,10,10,2,3,3,10]);


1
2
3
4
5
6
7
8
9
10
11
12
var arr = [2, 1, 2, 2, 4, 4, 2, 5];

function returnDuplicates(arr) {
  return arr.reduce(function(dupes, val, i) {
    if (arr.indexOf(val) !== i && dupes.indexOf(val) === -1) {
      dupes.push(val);
    }
    return dupes;
  }, []);
}

alert(returnDuplicates(arr));

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


下面的函数(前面提到的消除重复函数的变体)似乎完成了这个技巧,返回test2,1,7,5作为输入["test","test2","test2",1,1,2,3,4,5,6,7,7,10,22,43,1,5,8]

注意,这个问题在javascript中比在大多数其他语言中都要奇怪,因为一个javascript数组可以容纳任何东西。注意,使用排序的解决方案可能需要提供一个适当的排序功能——我还没有尝试过这个路由。

这个特定的实现至少适用于字符串和数字。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function findDuplicates(arr) {
    var i,
        len=arr.length,
        out=[],
        obj={};

    for (i=0;i<len;i++) {
        if (obj[arr[i]] != null) {
            if (!obj[arr[i]]) {
                out.push(arr[i]);
                obj[arr[i]] = 1;
            }
        } else {
            obj[arr[i]] = 0;            
        }
    }
    return out;
}

使用"includes"测试元素是否已经存在。

1
2
3
4
5
6
7
8
9
10
var arr = [1, 1, 4, 5, 5], darr = [], duplicates = [];

for(var i = 0; i < arr.length; i++){
  if(darr.includes(arr[i]) && !duplicates.includes(arr[i]))
    duplicates.push(arr[i])
  else
    darr.push(arr[i]);
}

console.log(duplicates);
1
2
3
4
5
6
7
8
9
10
11
12
Array with duplicates
<p>
[1, 1, 4, 5, 5]
</p>
Array with distinct elements
<p>
[1, 4, 5]
</p>
duplicate values are
<p>
[1, 5]
</p>


ES6提供了集合数据结构,它基本上是一个不接受重复项的数组。使用集合数据结构,可以很容易地找到数组中的重复项(只使用一个循环)。

这是我的密码

1
2
3
4
5
6
7
8
9
10
11
12
function findDuplicate(arr) {
var set = new Set();
var duplicates = new Set();
  for (let i = 0; i< arr.length; i++) {
     var size = set.size;
     set.add(arr[i]);
     if (set.size === size) {
         duplicates.add(arr[i]);
     }
  }
 return duplicates;
}

这里有一个非常简单的方法:

1
2
3
4
5
6
7
var codes = dc_1.split(',');
var i = codes.length;
while (i--) {
  if (codes.indexOf(codes[i]) != i) {
    codes.splice(i,1);
  }
}

我刚刚想出了一个简单的方法,用一个数组过滤器来实现这一点。

1
2
3
4
5
6
7
8
    var list = [9, 9, 111, 2, 3, 4, 4, 5, 7];
   
    // Filter 1: to find all duplicates elements
    var duplicates = list.filter(function(value,index,self) {
       return self.indexOf(value) !== self.lastIndexOf(value) && self.indexOf(value) === index;
    });
   
    console.log(duplicates);


1
2
3
4
5
6
7
8
9
10
var input = ['a', 'b', 'a', 'c', 'c'],
    duplicates = [],
    i, j;
for (i = 0, j = input.length; i < j; i++) {
  if (duplicates.indexOf(input[i]) === -1 && input.indexOf(input[i], i+1) !== -1) {
    duplicates.push(input[i]);
  }
}

console.log(duplicates);


只是为了增加一些理论。

在比较模型中,查找重复项的下限为o(n*log(n)。所以从理论上讲,你不能做得比第一次排序然后通过按顺序列出删除找到的所有重复项。

如果希望在线性(o(n))预期时间内找到重复项,可以散列列表中的每个元素;如果发生冲突,请将其删除/标记为重复项,然后继续。


我觉得最简单的解决方案就是使用indexof

将唯一元素推送到数组的完整示例。

1
2
3
4
5
6
7
var arr = ['a','b','c','d','a','b','c','d'];
var newA = [];
for(var i = 0; i < arr.length; i++){
    if(newA.indexOf(arr[i]) === -1){
        newA.push(arr[i]);
    }
 }


我更喜欢这样做的功能方式。

1
2
3
4
5
6
7
8
function removeDuplicates(links) {
    return _.reduce(links, function(list, elem) {
        if (list.indexOf(elem) == -1) {
            list.push(elem);
        }  
        return list;
    }, []);
}

它使用下划线,但数组也有一个reduce函数


遵循逻辑将变得越来越容易和快速

1
2
3
4
5
// @Param:data:Array that is the source
// @Return : Array that have the duplicate entries
findDuplicates(data: Array): Array {
        return Array.from(new Set(data)).filter((value) => data.indexOf(value) !== data.lastIndexOf(value));
      }

优势:

  • 单线:-P
  • 所有内置数据结构有助于提高效率
  • 更快
  • 逻辑描述:

  • 转换为set以删除所有重复项
  • 迭代设定值
  • 在源数组中检查条件"values first index is not equal to the last index"==>的每个设置值,然后将其推断为重复项,否则它是"唯一的"
  • 注意:map()和filter()方法效率更高,速度更快。


    仅限ES5(即,IE8及以下版本需要filter()polyfill):

    1
    2
    3
    4
    5
    6
    7
    var arrayToFilter = [ 4, 5, 5, 5, 2, 1, 3, 1, 1, 2, 1, 3 ];

    arrayToFilter.
        sort().
        filter( function(me,i,arr){
           return (i===0) || ( me !== arr[i-1] );
        });

    1
    2
    3
    4
    5
    6
    function GetDuplicates(arr) {
        var i = 0, m = [];
        return arr.filter(function (n) {
            return !m[n] * ~arr.indexOf(n, m[n] = ++i);
        });
    }

    我认为下面是最简单和最快的O(N)方法来实现您的要求:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    function getDuplicates( arr ) {
      var i, value;
      var all = {};
      var duplicates = [];

      for( i=0; i<arr.length; i++ ) {
        value = arr[i];
        if( all[value] ) {
          duplicates.push( value );
          all[value] = false;
        } else if( typeof all[value] =="undefined" ) {
          all[value] = true;
        }
      }

      return duplicates;
    }

    或对于ES5或更高版本:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    function getDuplicates( arr ) {
      var all = {};
      return arr.reduce(function( duplicates, value ) {
        if( all[value] ) {
          duplicates.push(value);
          all[value] = false;
        } else if( typeof all[value] =="undefined" ) {
          all[value] = true;
        }
        return duplicates;
      }, []);
    }

    我不喜欢大多数答案。

    为什么?太复杂,太多的代码,效率太低的代码,很多人都没有回答这个问题,这是为了找到重复项(而不是给出一个没有重复项的数组)。

    下一个函数返回所有重复项:

    1
    2
    3
    4
    5
    6
    function GetDuplicates(arr) {
      var i, out=[], obj={};
      for (i=0; i < arr.length; i++)
        obj[arr[i]] == undefined ? obj[arr[i]] ++ : out.push(arr[i]);
      return out;
    }

    因为在大多数情况下,返回所有重复的值是没有用的,而只是为了告诉存在哪些重复的值。在这种情况下,返回具有唯一重复项的数组;-)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    function GetDuplicates(arr) {
      var i, out=[], obj={};
      for (i=0; i < arr.length; i++)
        obj[arr[i]] == undefined ? obj[arr[i]] ++ : out.push(arr[i]);
      return GetUnique(out);
    }

    function GetUnique(arr) {
      return $.grep(arr, function(elem, index) {
        return index == $.inArray(elem, arr);
      });
    }

    也许其他人也这么认为。


    这可能是从数组中永久删除重复项的最快方法之一。比这里的大多数功能快10倍,比Safari快78倍

    1
    2
    3
    4
    5
    6
    7
    function toUnique(a,b,c){//array,placeholder,placeholder
     b=a.length;
     while(c=--b)while(c--)a[b]!==a[c]||a.splice(c,1)
    }
    var array=[1,2,3,4,5,6,7,8,9,0,1,2,1];
    toUnique(array);
    console.log(array);
  • 测试:http://jspef.com/wgu
  • 演示:http://jsfiddle.net/46s7g/
  • 更多:https://stackoverflow.com/a/25082874/2450730
  • 如果你不能阅读上面的代码,请阅读一本javascript书,或者这里有一些关于较短代码的解释。https://stackoverflow.com/a/21353032/2450730

    编辑如注释中所述,此函数返回一个具有唯一性的数组,但问题要求查找重复项。在这种情况下,对该函数的简单修改允许将重复项推送到数组中,然后使用前面的函数toUnique删除重复项的重复项。

    1
    2
    3
    4
    5
    6
    7
    function theDuplicates(a,b,c,d){//array,placeholder,placeholder
     b=a.length,d=[];
     while(c=--b)while(c--)a[b]!==a[c]||d.push(a.splice(c,1))
    }
    var array=[1,2,3,4,5,6,7,8,9,0,1,2,1];

    toUnique(theDuplicates(array));


    在O(N)时间复杂性(无排序)中解决上述问题。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    var arr = [9, 9, 111, 2, 3, 4, 4, 5, 7];

    var obj={};

    for(var i=0;i<arr.length;i++){
        if(!obj[arr[i]]){
            obj[arr[i]]=1;
        } else {
            obj[arr[i]]=obj[arr[i]]+1;
        }
    }
    var result=[]
    for(var key in obj){
        if(obj[key]>1){
            result.push(Number(key)) // change this to result.push(key) to find duplicate strings in an array
        }
    }

    console.log(result)


    修改@raphaelmontanaro的解决方案,借用@nosredna的博客,如果您只想从数组中识别重复的元素,可以这样做。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    function identifyDuplicatesFromArray(arr) {
            var i;
            var len = arr.length;
            var obj = {};
            var duplicates = [];

            for (i = 0; i < len; i++) {

                if (!obj[arr[i]]) {

                    obj[arr[i]] = {};

                }

                else
                {
                    duplicates.push(arr[i]);
                }

            }
            return duplicates;
        }

    感谢您的优雅解决方案,@nosredna!


    一班轮

    1
    2
    3
    var arr = [9,1,2,4,3,4,9]
    console.log(arr.filter((ele,indx)=>indx!==arr.indexOf(ele))) //get the duplicates
    console.log(arr.filter((ele,indx)=>indx===arr.indexOf(ele))) //remove the duplicates


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    //find duplicates:
    //sort, then reduce - concat values equal previous element, skip others

    //input
    var a = [1, 2, 3, 1, 2, 1, 2]

    //short version:
    var duplicates = a.sort().reduce((d, v, i, a) => i && v === a[i - 1] ? d.concat(v) : d, [])
    console.log(duplicates); //[1, 1, 2, 2]

    //readable version:
    var duplicates = a.sort().reduce((output, element, index, input) => {
      if ((index > 0) && (element === input[index - 1]))
        return output.concat(element)
      return output
    }, [])
    console.log(duplicates); //[1, 1, 2, 2]


    最快的解决方法实际上是用一个标志

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    var values = [4,2,3,1,4]

    // solution
    const checkDuplicate = list => {
      var hasDuplicate = false;
      list.sort().sort((a, b) => {
        if (a === b) hasDuplicate = true
      })
      return hasDuplicate
    }

    console.log(checkDuplicate(values))


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

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

    这应该是在数组中实际查找重复值的最短和最简单的方法之一。

    1
    2
    3
    4
    5
    6
    var arr = [1,2,3,4,5,6,7,8,1,2,3,4,5,3,3,4];
    var data = arr.filter(function(item,index,arr){
      return arr.indexOf(item) != arr.lastIndexOf(item) && arr.indexOf(item) == index;
    })

    console.log(data );


    这是我能想到的最有效的方法,因为不包括具有O(n)复杂性的Array.indexOf()Array.lastIndexOf(),并且在任何复杂的循环中使用O(n)将使完全复杂的O(n^2)。

    我的第一个循环的复杂性是O(n/2)或O((n/2)+1),因为哈希中搜索的复杂性是O(1)。第二个循环在数组中没有重复的情况下最复杂的是O(n),而在每个元素都有重复的情况下,最复杂的是O(n/2)。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    function duplicates(arr) {
      let duplicates = [],
          d = {},
          i = 0,
          j = arr.length - 1;

      // Complexity O(n/2)
      while (i <= j) {
        if (i === j)
          d[arr[i]] ? d[arr[i]] += 1 : d[arr[i]] = 1;  // Complexity O(1)
        else {
          d[arr[i]] ? d[arr[i]] += 1 : d[arr[i]] = 1;  // Complexity O(1)
          d[arr[j]] ? d[arr[j]] += 1 : d[arr[j]] = 1;  // Complexity O(1)
        }

        ++i;
        --j;
      }

      // Worst complexity O(n), best complexity O(n/2)
      for (let k in d) {
        if (d[k] > 1)
          duplicates.push(k);
      }

      return duplicates;

    }

    console.log(duplicates([5,6,4,9,2,3,5,3,4,1,5,4,9]));
    console.log(duplicates([2,3,4,5,4,3,4]));
    console.log(duplicates([4,5,2,9]));
    console.log(duplicates([4,5,2,9,2,5,9,4]));

  • 打印重复值
  • 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
     var arr = [1,2,3,4,13,2,3,4,3,4];

        // non_unique Printing
        function nonUnique(arr){
        var result = [];
        for(var i =0;i<arr.length;i++){
            if(arr.indexOf(arr[i],i+1) > -1){
                result.push(arr[i]);
            }
        }
        console.log(result);
        }nonUnique(arr);

        // unique Printing
        function uniqueDuplicateVal(arr){
           var result = [];
           for(var i =0;i<arr.length;i++){
            if(arr.indexOf(arr[i],i+1) > -1){
              if(result.indexOf(arr[i]) === -1]){
                 result.push(arr[i]);
              }
            }
           }    
        }
        uniqueDuplicateVal(arr)


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

    集合中的值只能出现一次;它在集合中是唯一的。

    1
    2
    3
    4
    5
    6
        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中不完全支持集合。


    与其他一些答案类似,但我使用forEach()使其更漂亮:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    function find_duplicates(data) {

        var track = {};
        var duplicates = [];

        data.forEach(function (item) {
            !track[item] ? track[item] = true : duplicates.push(item);
        });

        return duplicates;
    }

    如果一个值重复多次,则返回其所有重复值,如下所示:

    1
    2
    find_duplicates(['foo', 'foo', 'bar', 'bar', 'bar']);
    // returns ['foo', 'bar', 'bar']

    这可能是您想要的,否则您只需使用"唯一"筛选。


    这是我能想到的一个简单的ES5解决方案-

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    function duplicates(arr) {
      var duplicatesArr = [],
          uniqueObj = {};

      for (var i = 0; i < arr.length; i++) {
        if( uniqueObj.hasOwnProperty(arr[i]) && duplicatesArr.indexOf( arr[i] ) === -1) {
          duplicatesArr.push( arr[i] );
        }
        else {
          uniqueObj[ arr[i] ] = true;
        }
      }

      return duplicatesArr;
    }
    /* Input Arr: [1,1,2,2,2,1,3,4,5,3] */
    /* OutPut Arr: [1,2,3] */

    返回重复项并保留数据类型。

    具有O(4N)性能

    1
    2
    3
    4
    5
    6
    7
    const dupes = arr => {
      const map = arr.reduce((map, curr) => {
        return (map.set(curr, (map.get(curr) || 0) + 1), map)
      }, new Map());

      return Array.from(map).filter(([key, val])=> val > 1).map(([key, val]) => key)
    }

    具有O(2N)性能

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    const dupes = arr => {
      const map = arr.reduce((map, curr) => {
        return (map.set(curr, (map.get(curr) || 0) + 1), map)
      }, new Map());

      const dupes_ = [];
      for (let [key, val] of map.entries()) {
        if (val > 1) dupes_.push(key);
      }
      return dupes_;
    }

    从Raphael Montanaro的答案来看,它可以改进如下对数组/对象项的使用。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    function eliminateDuplicates(arr) {
      var len = arr.length,
          out = [],
          obj = {};

      for (var key, i=0; i < len; i++) {
        key = JSON.stringify(arr[i]);
        obj[key] = (obj[key]) ? obj[key] + 1 : 1;
      }
      for (var key in obj) {
        out.push(JSON.parse(key));
      }
      return [out, obj];
    }

    注意:对于不支持JSON的浏览器,需要使用JSON库。


    使用纯JS

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    function arr(){
      var a= [1,2,3,4,5,34,2,5,7,8,6,4,3,25,8,34,56,7,8,76,4,23,34,46,575,8564,53,5345657566];
      var b= [];
      b.push(a[0]);
      var z=0;

      for(var i=0; i< a.length; i++){
          for(var j=0; j< b.length; j++){
            if(b[j] == a[i]){
              z = 0;
              break;
            }
            else
              z = 1;
          }
          if(z)
            b.push(a[i]);
        }
      console.log(b);
    }

    您可以使用以下结构:

    1
    2
    3
    4
    var arr = [1,2,3,4,5,6,7,8,9,0,5];
    var duplicate = arr.filter(function(item, i, arr) {
      return -1 !== arr.indexOf(item, i + 1);
    })

    http://jsfiddle.net/vol7ron/gfj28/

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    var arr  = ['hello','goodbye','foo','hello','foo','bar',1,2,3,4,5,6,7,8,9,0,1,2,3];
    var hash = [];

    // build hash
    for (var n=arr.length; n--; ){
       if (typeof hash[arr[n]] === 'undefined') hash[arr[n]] = [];
       hash[arr[n]].push(n);
    }


    // work with compiled hash (not necessary)
    var duplicates = [];
    for (var key in hash){
        if (hash.hasOwnProperty(key) && hash[key].length > 1){
            duplicates.push(key);
        }
    }    
    alert(duplicates);
  • 结果将是hash数组,它将包含一组唯一的值和这些值的位置。所以如果有两个或更多的位置,我们可以确定这个值有一个重复的。因此,每一个地方都意味着复制品。

  • hash['hello']将返回[0,3],因为在arr[]的节点0和3中发现了"hello"。

    注:[0,3]的长度是用来确定它是否是副本的长度。

  • 使用for(var key in hash){ if (hash.hasOwnProperty(key)){ alert(key); } }将警告每个唯一值。


  • 下面是一个使用sort()和json.stringify()实现的方法

    https://gist.github.com/korczis/7598657

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    function removeDuplicates(vals) {
        var res = [];
        var tmp = vals.sort();

        for (var i = 0; i < tmp.length; i++) {
            res.push(tmp[i]);
                        while (JSON.stringify(tmp[i]) == JSON.stringify(tmp[i + 1])) {
                i++;
            }
        }

        return res;
    }
    console.log(removeDuplicates([1,2,3,4,5,4,3,3,2,1,]));


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    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;
            }
          }

    魔术

    1
    a.filter(( t={}, e=>!(1-(t[e]=++t[e]|0)) ))

    o(n)性能;我们假设您的数组在a中,并且它包含可以以独特方式(由JS在t[e]中进行隐式转换)的元素,例如数字=[4,5,4]、字符串=["aa"、"bb"、"aa"]、arraysnum=[1,2,3]、[43,2,3]、[1,2,3]、[1,2,3]等。此处解释,此处为唯一值

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    var a1 = [[2, 17], [2, 17], [2, 17], [1, 12], [5, 9], [1, 12], [6, 2], [1, 12]];
    var a2 = ['Mike', 'Adam','Matt', 'Nancy', 'Adam', 'Jenny', 'Nancy', 'Carl'];
    var a3 = [5,6,4,9,2,3,5,3,4,1,5,4,9];

    let nd = (a) => a.filter((t={},e=>!(1-(t[e]=++t[e]|0))))


    // Print
    let c= x => console.log(JSON.stringify(x));            
    c( nd(a1) );
    c( nd(a2) );
    c( nd(a3) );


    这是一种具有哈希表的单循环方法,用于对元素进行计数,并在计数为2时筛选数组,因为它返回第一个找到的重复项。

    优势:

    • 单回路
    • 在闭包中使用对象进行计数

    1
    2
    3
    4
    var array = [5, 0, 2, 1, 2, 3, 3, 4, 4, 8, 6, 7, 9, 4],
        duplicates = array.filter((h => v => (h[v] = (h[v] || 0) + 1) === 2)({}));
       
    console.log(duplicates);


    /*数组对象的indexof方法可用于比较数组项。IE是唯一本机不支持它的主要浏览器,但它很容易实现:*/

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    Array.prototype.indexOf= Array.prototype.indexOf || function(what, i){
        i= i || 0;
        var L= this.length;
        while(i<L){
            if(this[i]=== what) return i;
            ++i;
        }
        return -1;
    }

    function getarrayduplicates(arg){
        var itm, A= arg.slice(0, arg.length), dups= [];
        while(A.length){
            itm= A.shift();
            if(A.indexOf(itm)!= -1 && dups.indexOf(itm)== -1){
                dups[dups.length]= itm;
            }
        }
        return dups;
    }

    变量a1=[1,22,3,2,2,3,3,4,1,22,7,8,9];

    警报(GetArrayDuplicates(A1));

    对于非常大的数组,可以更快地从找到的数组中删除重复项,以便不再查看它们:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    function getarrayduplicates(arg){
        var itm, A= arg.slice(0, arg.length), dups= [];
        while(A.length){
            itm= A.shift();
            if(A.indexOf(itm)!= -1){
                dups[dups.length]= itm;
                while(A.indexOf(itm)!= -1){
                    A.splice(A.indexOf(itm), 1);
                }
            }
        }
        return dups;
    }

    在这里,我们每重复一次就输出一个副本。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    var arr = [9, 9, 9, 9, 111, 2, 3, 4, 4, 5, 7];
    arr.sort();

    var results = [];
    for (var i = 0; i < arr.length - 1; i++) {
        if (arr[i + 1] == arr[i]) {
            results.push(arr[i]);
        }
    }

    results = Array.from(new Set(results))

    console.log(results);


    以下是避免重复到javascript数组中的方法之一…它支持字符串和数字…

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     var unique = function(origArr) {
        var newArray = [],
            origLen = origArr.length,
            found,
            x = 0; y = 0;

        for ( x = 0; x < origLen; x++ ) {
            found = undefined;
            for ( y = 0; y < newArray.length; y++ ) {
                if ( origArr[x] === newArray[y] ) found = true;
            }
            if ( !found) newArray.push( origArr[x] );    
        }
       return newArray;
    }

    检查一下这个小提琴。


    我正在尝试改进@swilliams的答案,这将返回一个没有重复项的数组。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    // arrays for testing
    var arr = [9, 9, 111, 2, 3, 4, 4, 5, 7];

    // ascending order
    var sorted_arr = arr.sort(function(a,b){return a-b;});

    var arr_length = arr.length;
    var results = [];
    if(arr_length){
        if(arr_length == 1){
            results = arr;
        }else{
            for (var i = 0; i < arr.length - 1; i++) {
                if (sorted_arr[i + 1] != sorted_arr[i]) {
                    results.push(sorted_arr[i]);
                }
                // for last element
                if (i == arr.length - 2){
                    results.push(sorted_arr[i+1]);
                }
            }
        }
    }

    alert(results);

    下面是一个简单的小片段,用于查找不排序和两个循环的唯一和重复值。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    var _unique = function (arr) {
        var h = [], t = [];
        arr.forEach(function (n) {
            if (h.indexOf(n) == -1)
                h.push(n);
            else t.push(n);
        });
        return [h, t];
    }
    var result = _unique(["test",1,4,2,34,6,21,3,4,"test","prince","th",34]);
    console.log("Has duplicate values :" + (result[1].length > 0))  //and you can check count of duplicate values
    console.log(result[0]) //unique values
    console.log(result[1]) //duplicate values


    从数组/字符串中提取重复/重复值的最简单方法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    function getDuplicates(param) {
      var duplicates = {}

      for (var i = 0; i < param.length; i++) {
        var char = param[i]
        if (duplicates[char]) {
          duplicates[char]++
        } else {
          duplicates[char] = 1
        }
      }
      return duplicates
    }

    console.log(getDuplicates("aeiouaeiou"));
    console.log(getDuplicates(["a","e","i","o","u","a","e"]));
    console.log(getDuplicates([1, 2, 3, 4, 5, 1, 1, 2, 3]));


    原型库有一个uniq函数,它返回不带dupe的数组。不过,这只是工作的一半。


    这是基于发生次数的更高级的函数。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    function getMostDuplicated(arr, count) {
          const result = [];
          arr.forEach((item) => {
            let i = 0;
            arr.forEach((checkTo) => {
              if (item === checkTo) {
                i++;
                if (i === count && result.indexOf(item) === -1) {
                  result.push(item);
                }
              }
            });
          });
          return result;
    }

    arr = [1,1,1,2,5,67,3,2,3,2,3,1,2,3,4,1,4];
    result = getMostDuplicated(arr, 5); // result is 1
    result = getMostDuplicated(arr, 2); // result 1, 2, 3, 4
    console.log(result);


    这就是我如何用map实现它。它应该在O(N)时间内运行,应该有点容易喘气。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
        var first_array=[1,1,2,3,4,4,5,6];
        var find_dup=new Map;

        for (const iterator of first_array) {
                // if present value++
                if(find_dup.has(iterator)){
                    find_dup.set(iterator,find_dup.get(iterator)+1);
                }else{
                // else add it
                    find_dup.set(iterator,1);
                }
            }
        console.log(find_dup.get(2));

    然后您可以使用ecx1〔0〕来查找它是否有重复项(它应该给出>1)。


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    function remove_dups(arrayName){
      var newArray = new Array();

      label:for(var i=0; i<arrayName.length; i++ ){  

         for(var j=0; j<newArray.length;j++ ){
           if(newArray[j]==arrayName[i]){
             continue label;
           }
         }

         newArray[newArray.length] = arrayName[i];

      }

      return newArray;
    }


    我们将使用Javascript ES6功能来实现魔力!

    1
    2
    3
    4
    5
    6
    var arr = [9, 9, 111, 2, 3, 4, 4, 5, 7];
    const filtered = arr.filter((value, index) => {
     return arr.indexOf(value) >= index;
    });

    console.log(filtered);

    https://jsfiddle.net/97lxupnz/


    这里有一个不使用临时数组存储非重复的数组:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    // simple duplicate removal for non-object types
    Array.prototype.removeSimpleDupes = function() {
        var i, cntr = 0, arr = this, len = arr.length;

        var uniqueVal = function(val,n,len) { // remove duplicates
            var dupe = false;
                for (i = n; i < len; i++) {
                    if (typeof arr[i]!=="undefined" && val===arr[i]) { arr.splice(i,1); dupe = true; }
                }
            return (dupe) ? arr.length : len;
        };

        while (cntr < len) {
            len = uniqueVal(arr[cntr],cntr+1,len);
            cntr++;
        }

        return arr;
    };

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    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);
    }

    });


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    var arr = [4,5,1,1,2,3,4,4,7,5,2,6,10,9];
    var sorted_arr = arr.sort();
    var len = arr.length;
    var results = [];
    for (var i = 0; i < len; i++) {
      if (sorted_arr[i + 1] !== sorted_arr[i]) {
        results.push(sorted_arr[i]);
      }
    }
    document.write(results);


    没人惊讶地发布了this solution

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset=utf-8 />


    </head>
    <body>
     
           var list = [100,33,45,54,9,12,80,100];
           var newObj = {};
           var newArr = [];
            for(var i=0; i<list.length; i++){
              newObj[list[i]] = i;              
            }
            for(var j in newObj){
                newArr.push(j);  
            }
           console.log(newArr);
     
    </body>
    </html>


    您可以通过比较索引来继续:

    1
    2
    3
    function getDuplicate(array) {
        return array.filter((value, index) => array.value !== index)
    }

    在本文中,如果您使用jquery,那么对于重复检查非常有用。

    如何使用jquery在数组中查找重复项

    1
    var unique_values = {}; var list_of_values = []; $('input[name$="recordset"]').     each(function(item) {          if ( ! unique_values[item.value] ) {             unique_values[item.value] = true;             list_of_values.push(item.value);         } else {             // We have duplicate values!         }     });

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    //program to find the duplicate elements in arraylist

    import java.util.ArrayList;
    import java.util.Scanner;

    public class DistinctEle
    {
        public static void main(String args[])
        {
            System.out.println("Enter elements");
            ArrayList<Integer> abc=new ArrayList<Integer>();
            ArrayList<Integer> ab=new ArrayList<Integer>();
            Scanner a=new Scanner(System.in);
            int b;
            for(int i=0;i<=10;i++)
            {
                b=a.nextInt();
                if(!abc.contains(b))
                {
                    abc.add(b);
                }
                else
                {
                    System.out.println("duplicate elements"+b);
                }
            }
        }
    }