How to get unique values in a JavaScript array?

29

In PHP, when I have array with duplicate values, it is possible to get only single values through the function array_unique .

Example:

$array = ['a', 'b', 'b', 'c', 'c'];

array_unique($array); // ['a', 'b', 'c']

But I needed to do something similar in JavaScript, but I did not find a function that would do this natively.

What is the simplest way in JavaScript to get the unique values of a array ?

I'll leave this example array :

var array = ['a', 'b', 'b', 'c', 'c'];

console.log(array);
    
asked by anonymous 01.09.2016 / 14:48

6 answers

26

The solution I like best is to create a function to use along with filter() that is used precisely to determine which elements should be considered in an evaluation. It uses a functional style of programming where it matters what it does and not how it does.

function unique(value, index, self) { 
    return self.indexOf(value) === index;
}

var array = ['a', 'b', 'b', 'c', 'c'];
var unique = array.filter(unique);
console.log(unique);

Font .

I placed GitHub for future reference .

filter() is a function that scans all elements of array and sends it to a callback function defined by the programmer. In this function it makes a comparison if it is the first occurrence of the value and only if it is that filter() will consider as part of the new array .

The indexOf() gives the position of the first occurrence. If it hits the current index of the element searched, it is a value that matters in the criterion adopted. If it does not hit it means that it is already at least a second occurrence of that value, which does not matter.

This should work on most browsers currently used, it just does not work on those that are already considered very old.

    
01.09.2016 / 14:52
19

Here are 4 variants:

const array = ['a', 'b', 'b', 'c', 'c'];

using JavaScript of the future

const unique = [...new Set(array)];

As @stderr you mentioned in his answer are already planned (not yet officially released) two concepts that can be used to the end of the question. One is the Set , which is a new way to organize iterables. The other is the spread syntax that allows you to render / convert iterable, more or less as an indication to write the object "in extenso". In this case combining the two, gives what is asked in the question.

This solution still solves the problem that Gabriel mentioned and that exists in the solution with .filter() . (example: link )

Using .filter :

const unique = array.filter((el, i, arr) => arr.indexOf(el) == i);
console.log(unique); // ["a", "b", "c"]

The .filter method is natively available to arrays and accepts a function (callback). This function receives 3 arguments: the element to be iterated, the index (position) that is being iterated, and the original array. Using arr.indexOf(el) == i we ensure that only the first time each duplicate appears resolves to true , thus clearing the other elements.

Using .reduce and a ternary checker.

const unique = array.reduce(
    (arr, el) => arr.concat(arr.includes(el) ? [] : [el]), []
);
console.log(unique); // ["a", "b", "c"]

In this case with .reduce we can join elements to an array initialized in the second argument of the reduce method. It iterates all the positions of the array and with the ternary we check if the element already exists in the new array that is being created within the array.

Using an object to avoid duplicating keys

(only useful when we use Primitives )

const unique = ((obj, arr) => {
    arr.forEach(el => obj[el] = true);
    return Object.keys(obj);
})({}, array);
console.log(unique); // ["a", "b", "c"]

In this case we populate an object with keys formed by the elements of the initial array. Since objects only allow unique keys, when the iteration is complete we can return Object.keys(obj) which gives a new array with these unique keys.

    
01.09.2016 / 14:55
16

ES6 +

From ES6 you can also use Set

  

The Set object lets you store unique values of any type, whether   primitive values or object references.

See an example:

var valores = ['a', 'b', 'b', 'c', 'c', 1, 2, 2, 3];

var unique = new Set(valores);

alert([...unique]);
    
01.09.2016 / 15:13
8

Using array.filter

function array_unique(array){
    return array.filter(function(el, index, arr) {
        return index == arr.indexOf(el);
    });
}

var array = ['a', 'b', 'b', 'c', 'c'];

console.log('Array original:');
console.log( array);
console.log('Array após utilização de array_unique:');
console.log( array_unique(array));
    
01.09.2016 / 14:53
5

Very simple, it goes through the array and places the items in a temporary array, and checks whether or not the item exists in the temporary array.

function array_unique(array){
	var unique = [];
	for(var i in array){
		if(unique.indexOf(array[i])==-1){
			unique.push(array[i]);
		}
	}
	
	return unique;
}

var array = ['a', 'b', 'b', 'c', 'c'];
console.log(array_unique(array));
    
01.09.2016 / 14:56
4

Another solution would be.

Array.prototype.getUnique = function(){
   var u = {}, a = [];
   for(var i = 0, l = this.length; i < l; ++i){
      if(u.hasOwnProperty(this[i])) {
         continue;
      }
      a.push(this[i]);
      u[this[i]] = 1;
   }
   return a;
}

var array = ['a', 'b', 'b', 'c', 'c'];
array.getUnique();

Source: SOEN

    
01.09.2016 / 15:04