Get all non-unique values (i.e.: duplicate/more th

2018-12-31 00:39发布

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't actually need their indexes or how many times they are duplicated.

I know I can loop through the array and check all the other values for a match, but it seems like there should be an easier way. Any ideas? Thanks!

Similar question:

30条回答
旧人旧事旧时光
2楼-- · 2018-12-31 01:21

using underscore.js

function hasDuplicate(arr){
    return (arr.length != _.uniq(arr).length);
}
查看更多
大哥的爱人
3楼-- · 2018-12-31 01:24

Here is a very light and easy way:

var codes = dc_1.split(',');
var i = codes.length;
while (i--) {
  if (codes.indexOf(codes[i]) != i) {
    codes.splice(i,1);
  }
}
查看更多
与君花间醉酒
4楼-- · 2018-12-31 01:25

Here is mine simple and one line solution.

It searches not unique elements first, then makes found array unique with the use of Set.

So we have array of duplicates in the end.

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

查看更多
余欢
5楼-- · 2018-12-31 01:25

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

查看更多
零度萤火
6楼-- · 2018-12-31 01:25

This is my answer from the duplicate thread (!):

Got tired of seeing all bad examples with for-loops or jQuery. Javascript has the perfect tools for this nowadays: sort, map and reduce.

Find duplicate items

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

More functional syntax:

@Dmytro-Laptin pointed out some code code be removed. This is a more compact version of the same code. Using some ES6 tricks and higher order functions:

const names = ['Mike', 'Matt', 'Nancy', 'Adam', 'Jenny', 'Nancy', 'Carl']

const count = names => 
  names.reduce((a, b) => 
    Object.assign(a, {[b]: (a[b] || 0) + 1}), {})

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

Using Function.prototype.bind:

  // prep
  const arr = Array.from('Learn more javascript dude');
  const counter = (prev, next) => Object.assign(prev, { [next] : (prev[next] || 0) + 1 });
  const singles = function(key){ return this[key] === 1 };
  const multiples = function(key){ return this[key] > 1 };

  // work
  const counted = arr.reduce(counter, {});
  const filtered = Object.keys(counted).filter(multiples.bind(counted));

  //[ "e", "a", "r", " ", "d" ]
  console.log(filtered);
查看更多
一个人的天荒地老
7楼-- · 2018-12-31 01:26

Find unique values from 3 arrays (or more):

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]

Just a polyfill for array indexOf for old browsers:

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

jQuery solution using "inArray":

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

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

instead of adding the 'Array.prototype.indexOf'

查看更多
登录 后发表回答