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

后端 未结 30 3246
再見小時候
再見小時候 2020-11-21 04:35

I need to check a JavaScript array to see if there are any duplicate values. What\'s the easiest way to do this? I just need to find what the duplicated values are - I don\'

相关标签:
30条回答
  • 2020-11-21 05:35

    This is probably one of the fastest way to remove permanently the duplicates from an array 10x times faster than the most functions here.& 78x faster in safari

    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);
    
    1. Test: http://jsperf.com/wgu
    2. Demo: http://jsfiddle.net/46S7g/
    3. More: https://stackoverflow.com/a/25082874/2450730

    if you can't read the code above ask, read a javascript book or here are some explainations about shorter code. https://stackoverflow.com/a/21353032/2450730

    EDIT As stated in the comments this function does return an array with uniques, the question however asks to find the duplicates. in that case a simple modification to this function allows to push the duplicates into an array, then using the previous function toUnique removes the duplicates of the duplicates.

    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));
    
    0 讨论(0)
  • 2020-11-21 05:35

    ES6 offers the Set data structure which is basically an array that doesn't accept duplicates. With the Set data structure, there's a very easy way to find duplicates in an array (using only one loop).

    Here's my code

    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;
    }
    
    0 讨论(0)
  • 2020-11-21 05:36

    UPDATED: The following uses an optimized combined strategy. It optimizes primitive lookups to benefit from hash O(1) lookup time (running unique on an array of primitives is O(n)). Object lookups are optimized by tagging objects with a unique id while iterating through so so identifying duplicate objects is also O(1) per item and O(n) for the whole list. The only exception is items that are frozen, but those are rare and a fallback is provided using an array and 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;
    }();
    

    If you have ES6 Collections available, then there is a much simpler and significantly faster version. (shim for IE9+ and other browsers here: 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;
        }
      });
    }
    
    0 讨论(0)
  • 2020-11-21 05:36

    This is my proposal (ES6):

    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]
    
    0 讨论(0)
  • 2020-11-21 05:36

    ES5 only (i.e., it needs a filter() polyfill for IE8 and below):

    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 讨论(0)
  • 2020-11-21 05:37

    Fast and elegant way using es6 object destructuring and reduce

    It runs in O(n) (1 iteration over the array) and doesn't repeat values that appear more than 2 times

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

    0 讨论(0)
提交回复
热议问题