7

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?

nbrooks
  • 18,126
  • 5
  • 54
  • 66
tardjo
  • 1,594
  • 5
  • 22
  • 38
  • Seem like there are plenty of other questions out there to help you, have you searched to see what else is out there? http://stackoverflow.com/questions/5381621/jquery-function-to-get-all-unique-elements-from-an-array – Dan Aug 18 '14 at 04:44

9 Answers9

3

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;
}
Manish Kr. Shukla
  • 4,447
  • 1
  • 20
  • 35
2

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

Umesh Sehta
  • 10,555
  • 5
  • 39
  • 68
2

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;
}
Rahul Tripathi
  • 168,305
  • 31
  • 280
  • 331
  • I do like the approach of keeping track of the values seen so far in a map, but this isn't really solving the OP's problem. This takes an array and returns a new array containing only the unique values. The question was requesting a method which returns a boolean value, indicating whether the given array contained duplicates. – nbrooks Aug 18 '14 at 05:27
2

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

Prabhu Murthy
  • 9,031
  • 5
  • 29
  • 36
  • to scan through a JS array and determine if all the elements are unique, or whether the array contains duplicates, we dont need a loop.we can sort an array and check if first and last element of array maches...this is not the best way – sumit Aug 18 '14 at 06:01
  • 1
    @timus2001: thanks. i didnt propose it as the best option. but just added this as one of the alternative to the lot of other good answers. – Prabhu Murthy Aug 18 '14 at 06:35
1

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;
}
fanfan1609
  • 179
  • 2
  • 8
1

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.

huocp
  • 3,898
  • 1
  • 17
  • 29
  • 1
    It's always great to see answers thinking with big O notations :D – Derek 朕會功夫 Aug 18 '14 at 05:13
  • 2
    Actually, this would be `O(n^2)` in the worst-case. You are assuming that `indexOf` is `O(1)`, but think about what it's doing—it's iterating through the whole array (size `n`) searching for a match. Even though you can't see the loop, it's still effectively a nested loop. – nbrooks Aug 18 '14 at 05:17
1
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.

nbrooks
  • 18,126
  • 5
  • 54
  • 66
0
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>
sumit
  • 15,003
  • 12
  • 69
  • 110
0

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