nackjicholson
nackjicholson

Reputation: 4839

Using lodash to check whether an array has duplicate values

What do you all think would be the best (best can be interpreted as most readable or most performant, your choice) way to write a function using the lodash utilities in order to check an array for duplicate values.

I want to input ['foo', 'foo', 'bar'] and have the function return true. And input ['foo', 'bar', 'baz'] and have the function return false.

Upvotes: 37

Views: 46779

Answers (6)

Akrion
Akrion

Reputation: 18515

As of ES6 you can simply use Set so this becomes:

let hasDuplicates = arr => new Set(arr).size != arr.length

console.log(hasDuplicates([5,3,2,1,2,1,2,1]))
console.log(hasDuplicates([1,2,3,4,5]))

Which somewhat negates the use of lodash in this particular case.

Upvotes: 22

Hushen Savani
Hushen Savani

Reputation: 1

No need to use lodash, use following code instead:

function getDuplicates(array, key) {
  return array.filter(e1=>{
    if(array.filter(e2=>{
      return e1[key] === e2[key];
    }).length > 1) {
      return e1;
    }
  })
}

Upvotes: 0

agershun
agershun

Reputation: 4107

You can try this code:

function hasDuplicates(a) {
  return _.uniq(a).length !== a.length; 
}

var a = [1,2,1,3,4,5];
var b = [1,2,3,4,5,6];

document.write(hasDuplicates(a), ',',hasDuplicates(b));
<script src="http://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.1.0/lodash.min.js"></script>

Upvotes: 69

user663031
user663031

Reputation:

You could check that there is _.some element in the array which does not return its own location when looked up in the array. In other words, there is at least one element which has a match earlier in the array.

function hasDuplicates(array) {
    return _.some(array, function(elt, index) { 
        return array.indexOf(elt) !== index; 
    });
}

Perhaps this is faster than the _.uniq solution, since it will identify the first duplicated element right away without having to compute the entire unique-ified array.

Or, depending on your coding style and desire for readability, and if you want to use ES6 arrow functions for brevity:

var earlierMatch  = (elt, index, array) => array.indexOf(elt) !== index;
var hasDuplicates = array => _.some(array, earlierMatch);

Upvotes: 7

sebnukem
sebnukem

Reputation: 8323

I don't know lodash but I submit:

_.any(_.countBy(['foo', 'foo', 'bar']), function(x){ return x > 1; });

The problem with all the solutions proposed so far is that the entire input array needs processing to get an answer, even if the answer is obvious from the first 2 elements of the array.

Upvotes: 2

Paul Wostenberg
Paul Wostenberg

Reputation: 449

Well, there's always. lodash's _.uniq() function. That function actually returns a new array that only contains unique values, so checking to see if the length of the array has changed would get you your 'true' or 'false' value to return yourself, I believe.

Upvotes: 3

Related Questions