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

Posted

技术标签:

【中文标题】获取数组中的所有非唯一值(即:重复/多次出现)【英文标题】:Get all non-unique values (i.e.: duplicate/more than one occurrence) in an array 【发布时间】:2010-10-24 20:33:11 【问题描述】:

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

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

类似问题:

Get all unique values in a JavaScript array (remove duplicates)

【问题讨论】:

对于这个问题的要求似乎有多年的困惑。我需要知道数组中的哪些元素被重复:“我只需要找到重复的值是什么”。正确答案不应从数组中删除重复项。这与我想要的相反:重复的列表,而不是唯一元素的列表。 github.com/lodash/lodash/issues/4852#issuecomment-666366511 我会添加这个作为答案,但考虑到答案的长度,它永远不会被看到 【参考方案1】:

您可以对数组进行排序,然后遍历它,然后查看下一个(或上一个)索引是否与当前索引相同。假设你的排序算法很好,这应该小于 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://***.com/a/57532964/8119511

【讨论】:

"假设你的排序算法很好,这应该小于 O^2"。具体来说,它可能是 O(n*log(n))。 这个脚本不能很好地处理超过 2 个重复项(例如 arr = [9, 9, 9, 111, 2, 3, 3, 3, 4, 4, 5, 7]; @swilliams 我认为这些指导方针并没有说明不使用i++。相反,他们说不要写j = i + +j。恕我直言,两件不同的事情。我觉得i += 1比简单漂亮的i++更让人迷惑:) -1 这个答案在很多层面上都是错误的。首先var sorted_arr = arr.sort() 是无用的:arr.sort() 改变了原始数组(这本身就是一个问题)。这也丢弃了一个元素。 (运行上面的代码。9 会发生什么?) cc @dystroy 更干净的解决方案是results = arr.filter(function(elem, pos) return arr.indexOf(elem) == pos; ) 所有人:问题要求显示重复值,而不是删除它们。请不要编辑/破坏代码来试图让它做一些它不想做的事情。警报应显示重复的值。【参考方案2】:

Prototype 库有一个uniq 函数,它返回没有欺骗的数组。但这只是工作的一半。

【讨论】:

【参考方案3】:

你可以添加这个函数,或者调整它并将它添加到 Javascript 的 Array 原型中:

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);

【讨论】:

这是最好的解决方案,但要小心将其添加到数组原型中,因为如果循环遍历这些值,将会弄乱 IE。 @RoyTinker perl 也支持它们,但我不知道 javascript 是否支持 不执行 OP 要求的操作,返回重复项。【参考方案4】:

如果你想消除重复,试试这个很好的解决方案:

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;


console.log(eliminateDuplicates([1,6,7,3,6,8,1,3,4,5,1,7,2,6]))

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

【讨论】:

那是很好的代码,但不幸的是它不能满足我的要求。 上面的代码(这是我的——那是我的博客)让你非常接近。一个小小的调整,你就在那里。首先,你可以看看 arr.length 和 out.length 是否相同。如果它们相同,则没有重复的元素。但你想要更多。如果您想在发生欺骗时“捕捉”它们,请检查数组的长度是否在 obj[arr[i]]=0 行之后增加。漂亮,嗯? :-) 感谢您的好话,Raphael Montanaro。 @MarcoDemaio:呃,不,为什么代码不能使用空格?您可以在属性名称中添加您喜欢的任何内容 - 只是不能使用点语法来访问带有空格的属性(也不能使用会破坏解析的各种其他字符的道具)。 @Gijs:+1 你是对的。我不知道。但是当它是一个对象数组时它仍然不起作用。 这个算法还有一个副作用,就是返回一个排序好的数组,这可能不是你想要的。【参考方案5】:

这应该可以得到你想要的,只是重复。

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.

【讨论】:

【参考方案6】:

只是在上面添加一些理论。

在比较模型中,查找重复项的下限为 O(n*log(n)。所以理论上,你不能比先排序然后再通过 列出按顺序删除您找到的所有重复项。

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

【讨论】:

同意。在这里尝试不同方法的唯一原因是速度取决于运行时中各种事物的实现程度。这将因浏览器而异。对于简短的列表,您如何解决问题可能并不重要。对于大型数组,它确实如此。【参考方案7】:

下面的函数(已经提到的消除重复函数的变体)似乎可以解决问题,为输入返回 test2,1,7,5 ["test", "test2", "test2", 1, 1, 1、2、3、4、5、6、7、7、10、22、43、1、5、8]

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

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

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;

【讨论】:

【参考方案8】:

/* Array 对象的 indexOf 方法对于比较数组项很有用。 IE是唯一不原生支持的主流浏览器,但是实现起来很容易: */

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;

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

警报(getarrayduplicates(a1));

对于非常大的数组,在找到重复项时从数组中删除它们会更快,这样就不会再次查看它们:

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;

【讨论】:

【参考方案9】:

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

ES2015

//          ??  ?   ?             ? 
var arr =  [1,2,2,3,3,4,5,6,2,3,7,8,5,22],
    arr2 = [1,2,511,12,50],
    arr3 = [22,0],
    merged,
    nonUnique;

// Combine all the arrays to a single one
merged = arr.concat(arr2, arr3)

// create a new (dirty) Array with only the non-unique items
nonUnique = merged.filter((item,i) => merged.includes(item, i+1))

// Cleanup - remove duplicate & empty items items 
nonUnique = [...new Set(nonUnique)]

console.log(nonUnique)

预 ES2015:

在下面的示例中,我选择在Array prototype 之上叠加一个unique 方法,允许从任何地方访问并且具有更多“声明性” 语法.我不建议在大型项目中使用这种方法,因为它很可能会与具有相同自定义名称的另一种方法发生冲突。

Array.prototype.unique = function () 
    var arr = this.sort(), i=arr.length; // input must be sorted for this to work
    while(i--)
      arr[i] === arr[i-1] && arr.splice(i,1) // remove duplicate item
    return arr


Array.prototype.nonunique = function () 
    var arr = this.sort(), i=arr.length, res = []; // input must be sorted for this to work
    while(i--)
      arr[i] === arr[i-1] && (res.indexOf(arr[i]) == -1) && res.push(arr[i]) 
    return res


//          ??  ?    ?            ? 
var arr =  [1,2,2,3,3,4,5,6,2,3,7,8,5,22],
    arr2 = [1,2,511,12,50],
    arr3 = [22,0],
    // merge all arrays & call custom Array Prototype - "unique"
    unique = arr.concat(arr2, arr3).unique(),
    nonunique = arr.concat(arr2, arr3).nonunique()

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

【讨论】:

+1 因为使用 Array.indexOf 的代码绝对更具可读性,但不幸的是它似乎比使用简单的嵌套循环要慢。即使在像 FF 一样天真地实现 Array.indexOf 的浏览器上也是如此。请看看我在这里做的这些测试:jsperf.com/array-unique2,让我知道你的想法。 @shekhardesigner - 更新的答案。 “r”是您搜索的数组 @vsync 我必须初始化 var r = []; 才能让您的代码正常工作。并且像魅力一样工作。 @shekhardesigner - 对不起,对于阵列原型解决方案,您不需要 r 变量 不执行 OP 要求的操作,返回重复项。【参考方案10】:

根据 Raphael Montanaro 的回答,它可以改进为与数组/对象项一起使用,如下所示。

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 库。

【讨论】:

【参考方案11】:

这是一个不使用临时数组来存储不重复的数组:

// 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;
;

【讨论】:

【参考方案12】:

我更喜欢这样做的函数方式。

function removeDuplicates(links) 
    return _.reduce(links, function(list, elem)  
        if (list.indexOf(elem) == -1) 
            list.push(elem);
           
        return list;
    , []);

这里使用下划线,但是Array也有reduce函数

【讨论】:

不执行 OP 要求的操作,返回重复项。【参考方案13】:

http://jsfiddle.net/vol7ron/gfJ28/

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 数组,其中包含一组唯一的值和这些值的位置。所以如果有2个或更多位置,我们可以确定该值有重复。因此,hash[&lt;value&gt;].length &gt; 1 的每个地方都表示重复。

    hash['hello'] 将返回 [0,3],因为在 arr[] 的节点 0 和 3 中找到了“hello”。

    注意:[0,3] 的长度用于确定它是否重复。

    使用for(var key in hash) if (hash.hasOwnProperty(key)) alert(key); 将提醒每个唯一值。

【讨论】:

【参考方案14】:
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;);

或者当添加到Array的prototyp.chain时

//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

【讨论】:

过滤器函数应该返回真或假,而不是元素本身。过滤包含 0 的数组不会返回它们。 另外,我假设i&amp;&amp; 是为了避免超出数组的范围,但这也意味着不会包含排序数组中的第一个元素。在您的示例中,结果数组中没有 1 。 IE。 return i&amp;&amp;v!==o[i-1]?v:0; 应该是 return v!==o[i-1];【参考方案15】:

更新:以下使用优化的组合策略。它优化了原始查找以受益于哈希 O(1) 查找时间(在原始数组上运行 unique 是 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 Collections 可用,那么有一个更简单且速度更快的版本。 (此处适用于 IE9+ 和其他浏览器的 shim: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;
    
  );

【讨论】:

真的吗?为什么要回答一个 2 年前就已经解决的问题? 我正在回答另一个问题,显然不小心点击了链接到这个问题的人,称其为重复项,最终克隆了我的答案并将我自己搞糊涂了。我经常编辑我的东西。 ***.com/questions/7683845/… 我认为不同的解决方案很好。该主题是否已过时并已解决并不重要,因为仍然可以提出不同的方法来做到这一点。这是计算机科学中的一个典型问题。 你可能想提一下,这依赖于 IE 【参考方案16】:
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;

【讨论】:

-1:不回答提出的问题,即识别受骗者,而不是删除他们。您可能还应该包含一些描述您的解决方案的文本。【参考方案17】:

如果你使用的是 Jquery,这篇文章对于重复检查很有用。

How to find the duplicates in an array using jquery

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!              );

【讨论】:

【参考方案18】:

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

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] );
    );

【讨论】:

我喜欢这个简单的解决方案。但是,如果您想要重复项,则需要首先找到这些重复项,然后使重复列表唯一。 [ 0, 4, 5, 5, 5, 2, 1, 3, 1, 1, 2, 1, 3 ].sort().filter( function(me,i,arr) return (i!==0 ) && ( me == arr[i-1] ); ).filter( function(me,i,arr) return (i===0) || ( me !== arr[i-1] ) ; );【参考方案19】:

使用 underscore.js

function hasDuplicate(arr)
    return (arr.length != _.uniq(arr).length);

【讨论】:

【参考方案20】:
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);

【讨论】:

【参考方案21】:

这是避免重复到 javascript 数组中的一种方法...它支持字符串和数字...

 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;

检查这个fiddle..

【讨论】:

不是所要求的。 问题不是删除重复项,而是找到它们。另外,您为什么不关心复杂性是 O(nlog(n))。也使用 n 个空格。【参考方案22】:

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

// 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);

【讨论】:

【参考方案23】:

使用下划线的另一种方式。 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;
, []);

【讨论】:

【参考方案24】:

这是一个非常轻巧的方法:

var codes = dc_1.split(',');
var i = codes.length;
while (i--) 
  if (codes.indexOf(codes[i]) != i) 
    codes.splice(i,1);
  

【讨论】:

最佳答案。如果用户想要重复元素数组,为此我更新了@brandon code var i = codes .length;变种重复 = []; while (i--) if (codes .indexOf(codes [i]) != i) if(duplicate.indexOf(codes [i]) === -1) duplicate.push(arr[i]) ; code.splice(i,1); 【参考方案25】:

我认为以下是完成您所要求的最简单和最快的 O(n) 方法:

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 或更高版本:

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;
  , []);

【讨论】:

【参考方案26】:

这是使用 sort() 和 JSON.stringify() 实现的一个

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

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,]));

【讨论】:

我没有投反对票,但问题是要找到所有重复项而不是删除它们。即使在简单的示例中,您的答案也不会起作用。【参考方案27】:

很惊讶没有人发帖this solution

<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>
</title>
</head>
<body>
  <script>
       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);
  </script>
</body>
</html>

【讨论】:

这不符合问题的要求。 @ScottSaunders:在 JavaScript 数组中查找重复值的最简单方法 问题是如何显示重复值,而不是唯一值。【参考方案28】:

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

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 的优雅解决方案!

【讨论】:

【参考方案29】:

我不喜欢大多数答案。

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

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

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;
  

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

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);
  );

也许其他人也这么认为。

【讨论】:

【参考方案30】:

这是我从重复线程 (!) 中的回答:

在 2014 年编写此条目时 - 所有示例都是 for 循环或 jQuery。 Javascript 有完美的工具:排序、映射和归约。

查找重复项

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 技巧和高阶函数:

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' ]

【讨论】:

@ChristianLandgren,“dict”变量在哪里声明?也许应该使用“计数”? dict 变量是粗箭头函数的参数。它是 function(dict) return Object.keys(dict) ... 的简写 请注意,由于 =&gt; 语法,这与较低版本的 IE 不兼容。

以上是关于获取数组中的所有非唯一值(即:重复/多次出现)的主要内容,如果未能解决你的问题,请参考以下文章

PSQL - 查找所有值并根据另一列中的非唯一值使其唯一

如何在javascript数组中存储所有包括重复(非唯一)对象?

Oracle:更新非唯一字段

在循环中多次重复数组中的项目?

对重复值求和时如何获得不同的总和?

获取嵌套数组/对象的数组中的所有唯一值(删除重复项)