11

I need to find the number of unique elements in an array.

var myArray = [ 10, 10, 20, 20, 30, 30, 40, 40, 40, 40, 50, 50, 50, 50, 60 ];

I want count = 6 (number of unique elements in array)

And, is there a way to do this without iterating through the array? (I assume that would be the fastest way?).

ANSWER: I used the .filter method as shown below. My actual array element is much more complex. I ended up iterating through my array and created a new array. Each element in the new array was a .substr of the old element. Then, the .filter method below worked great. THANKS to everyone!!

7
  • 2
    I think you can get help from here. stackoverflow.com/questions/11246758/… Commented Feb 9, 2014 at 16:31
  • Yep. Looked at that. But that's different. I only want one number. Commented Feb 9, 2014 at 16:32
  • Use underscore.js _.uniq(myArray).length. Commented Feb 9, 2014 at 16:33
  • You can create a object Commented Feb 9, 2014 at 16:33
  • do you mean pull in the library underscore? Commented Feb 9, 2014 at 16:34

5 Answers 5

14

ES6 offers a single line solution:

new Set(myArray).size
Sign up to request clarification or add additional context in comments.

1 Comment

myArray can also be a string. A fantastic use of ES6.
12

You need to keep a set of known values, and an auxilliary count. You can use .reduce():

var count = myArray.reduce(function(values, v) {
  if (!values.set[v]) {
    values.set[v] = 1;
    values.count++;
  }
  return values;
}, { set: {}, count: 0 }).count;

Starting with an empty set of values and a count of zero, this looks at each element to see whether it's been added to the set. If it hasn't, it's added, and the count is incremented.

3 Comments

so, in this case it returns count = 6 ? Is it the fastest way?
I set up a performance test between your method of reducing vs a vanilla Object set: jsperf.com/js-set-test
@Mr.Polywhirl For me the "reduce" is faster, but I suspect a big part of that is that the "simple" code is (correctly!) making a hasOwnProperty test. Otherwise the two approaches are almost exactly the same, if implemented slightly differently.
3

How about filter and length:

var len = myArray.filter(function(val, i, arr) { 
    return arr.indexOf(val) === i;
}).length;

6 Comments

hmmmm. so. what variable? is equal to 6 here?
I'm favoring your method for the simple reason that it necessitates less code. Two questions though. 1. is it as fast as the above two methods? and 2. I need some help understanding what (val, i, arr) mean. So, in my case, I need to find the "count" of a substring of an element in the array. So in this case for example, I need to find the number of unique occurrances of myArray.substr(3,6). I'm not sure how this maps to (val, i, arr)... thanks!
@hypermiler this is simpler, but for long arrays it's going to be expensive. The .indexOf operation has to perform a linear search, so the execution time tends to be proportional to the square of the length of the array (particularly when there are not many duplicates).
this is a very short array. Maybe max 30 elements. Usually much less. And the likelihood of duplicates is low.
|
1

If you happen to be using lodash:

_.uniq(myArray).length

Comments

0

You can now convert your array into a unique Array and compare lengths. Do this by changing it into Set and then back to an Array. If the Set is smaller then duplicates were removed and your original Array did not contain unique values.

const isUnique = (myArray.length === [...new Set(myArray)].length);

test:

const myArray=[1,2,2,3,4]; 
console.log(myArray.length === [...new Set(myArray)].length);
false

const myArray=[1,2,3,4]; 
console.log(myArray.length === [...new Set(myArray)].length);
true

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.