tardjo
tardjo

Reputation: 1654

Determining whether an array contains duplicate values

I would like to scan through a JS array and determine if all the elements are unique, or whether the array contains duplicates.

example :

my_array1 = [1, 2, 3] 
my_array2 = [1, 1, 1]

I want get result like this :

my_array1 must be return true, because this array element is unique
and array2 must be return false, because this array element is not unique

How can I go about writing this method?

Upvotes: 7

Views: 4241

Answers (9)

I just came up with this answer. I'm preparing for an interview. I think this is rock solid.

let r  = [1,9,2,3,8];
let r2 = [9,3,6,3,8];

let isThereDuplicates= r.slice().sort().some((item,index,ar)=>(item ===ar[index+1]));
console.log('r is: ',isThereDuplicates) // -> false. All numbers are unique

isThereDuplicates=  r2.slice().sort().some((item,index,ar)=>(item ===ar[index+1]));
console.log('r2 is: ',isThereDuplicates) //->true. 3 is duplicated

I first slice and sort without mutating the original array.

r.slice().sort()

Then I check that for at least one item, item is equal to the next item on the array.

.some((item,index,array)=>
    item === array[index+1]
);

Upvotes: 0

Prabhu Murthy
Prabhu Murthy

Reputation: 9261

if you want to check for uniqueness you can also do this.As stated on the comment i do not assert this is as the only best option.There are some great answers down below.

var arr = [2,3,4,6,7,8,9];
var uniq = []; // we will use this to store the unique numbers found
               // in the process for doing the comparison

var result = arr.slice(0).every(function(item, index, array){
  if(uniq.indexOf(item) > -1){
    // short circuit the loop
    array.length=0; //(B)
    return false;
  }else{
    uniq.push(item);
    return true;
  }
});

result --> true

arr.slice(0) creates a temporary copy of the array, on which the actual processing is done.This is because when the uniqueness criteria is met i clear the array (B) to short circuit the loop.This will make sure the processing stops as soon as the criteria is met.

And will be more nicer if we expose this as a method on a Array instance. so we can do something like this [1,2,3,5,7].isUnique();

Add the following snippet and you are ready to go

Array.prototype.isUnique = function() {
    var uniq = [];
    var result = this.slice(0).every(function(item, index, arr) {
        if (uniq.indexOf(item) > -1) {
            arr.length = 0;
            return false;
        } else {
            uniq.push(item);
            return true;
        }
    });
    return result;
};

arr.isUnique() --> true

DEMO

Upvotes: 2

sumit
sumit

Reputation: 15464

If you need to check all element are unique then following will do the trick

<script>
my_array1 = [11, 20, 3] 
my_array2 = [11, 11, 11]
var sorted1= my_array1.sort();
var sorted2= my_array2.sort();
if(sorted1[0]==sorted1[sorted1.length-1])
    alert('all same');
if(sorted2[0]==sorted2[sorted2.length-1])
    alert('all same');

</script>

Upvotes: 0

nbrooks
nbrooks

Reputation: 18233

function containsDuplicates(arr) {
    var seen = {};
    var duplicate = false;

    for (var i = 0; i < arr.length; i++) {
        if (seen[arr[i]]) {
            duplicate = true;
            break;
        }
        seen[arr[i]] = true;
    }

    return duplicate;
}

jsFiddle

Best-case: O(1) time and space - second element is the duplicate
Average/worst-case: O(n) time and space - no duplicates, or the duplicate is in the middle

Many of the answers here seem to be relying on some complex interspersion of array methods, which are inherently iterative, and generally don't seem appropriate for this fairly simple task. Algorithmically, this problem can be solved in O(n) time, but any nesting of indexOf/filter/map (or similar array methods) in a for loop means that your computation time will grow (at best) quadratically with your array size, rather than linearly. This is inefficient in time.

Now, in general, micro-optimization really is not necessary unless you have identified this to be a performance bottleneck in your application. But this kind of algorithm, in my opinion, is something you design (in pseudocode) and match to your application's needs before you even start coding. If you will have a huge data-set in your array, you will probably appreciate not having to look through it several times to get your answer. Of course, the caveat here is that you're trading time complexity for space complexity, since my solution requires O(n) space for caching previously seen values.

Upvotes: 1

user1375096
user1375096

Reputation:

The most efficient way to test uniqueness is:

function isUnique(arr) {
  for(var i = 0; i < arr.length; i++) {
    if (arr.indexOf(arr[i]) != i) return false;
  }
  return true;
}

This is O(n2) at worst case. At most time, it doesn't need to finish scanning for not-unique array.

Upvotes: 1

Umesh Sehta
Umesh Sehta

Reputation: 10683

try this :-

var my_array1 = [1, 2, 3] 
var my_array2 = [1, 1, 1]


function isUnique(obj)
{
   var unique=obj.filter(function(itm,i,a){
      return i==a.indexOf(itm);
   });   
   return unique.length == obj.length;  
 }


 alert(isUnique(my_array1))
 alert(isUnique(my_array2))

Demo

Upvotes: 1

fanfan1609
fanfan1609

Reputation: 179

I think you can try with Underscore js , a powerful javascript library

Example the way to use underscore

function checkUniqueArr(arr){
   var unique_arr = _.uniq(arr);
   return arr.length == unique_arr.length;
}

Upvotes: 1

Rahul Tripathi
Rahul Tripathi

Reputation: 172448

You may try like this:

function uniqueArray(arr) {
    var hash = {}, result = [];
    for ( var i = 0, l = arr.length; i < l; ++i ) {
        if ( !hash.hasOwnProperty(arr[i]) ) { 
            hash[ arr[i] ] = true;
            result.push(arr[i]);
        }
    }
    return result;
}

Upvotes: 2

Manish Kr. Shukla
Manish Kr. Shukla

Reputation: 4477

Sort your array first of all, and then go for a simple comparison loop.

function checkIfArrayIsUnique(arr)  {
   var myArray = arr.sort();

    for (var i = 0; i < myArray.length; i++) {
        if (myArray.indexOf(myArray[i]) !== myArray.lastIndexOf(myArray[i])) { 
            return false; 
        } 
    } 

    return true;
}

Upvotes: 3

Related Questions