Remove repeated elements within a Javascript array

Asked

Viewed 46,159 times

30

How to remove repeated elements within a Javascript array?

I have for example:

var array = ['foo', 'bar', 'foo'];

And I want to remove all duplicates to get:

['foo', 'bar']
  • You managed to solve your answer?

7 answers

39

You can use it like this:

var arr = ['foo', 'bar', 'foo'];
var novaArr = arr.filter(function(este, i) {
    return arr.indexOf(este) === i;
});
console.log(novaArr); //dá ['foo', 'bar']

In short version it would be:

var arr = ['foo', 'bar', 'foo'];
var novaArr = arr.filter((este, i) => arr.indexOf(este) === i);
console.log(novaArr); //dá ['foo', 'bar']

What this code does is use the .filter(). In this native function only pass the elements that give return with boleano value true. And what the function checks is whether the position of each element within the array is the same as the input the function passes.

That is to say arr.indexOf(este) gives the position/index of this element in the array, and the variable i that the function passes does the same. If they are equal then that element is "original", that is, it is the first time it appears. In the case of a duplicate, the value of i will match the position of the duplicate, but the arr.indexOf(este) will give the position the first time this value appears in the array.

This function is +/- recent and Internet Explorer only supports version 9. On the link I put up there is an alternative to IE8. Unfortunately IE7 is too old and as it has no prototype this solution does not apply.

  • 1

    It is good to note that filter is IE9+, but has a polyfill in the linked documentation in the reply.

  • 1

    @bfavaretto truth. I added info about it. Thank you!

  • I think it’s worth mentioning that since the complexity of this function is O(n 2), it can degrade in performance as the number of elements grows.

8

You can use the Set, entered in Ecmascript 2015 (ES6):

const arr = [1, 1, 2, 2, 3, 3, "teste", "teste"];
const arrUnique = [...new Set(arr)];

Do not attempt to use this medium to remove duplicate objects, since these are compared by reference.

Sources for further research:

8

To do with pure Javascript, as answered in this link: https://stackoverflow.com/a/9229821

uniqueArray = myArray.filter(function(elem, pos, self) {
    return self.indexOf(elem) == pos;
})

8

a = ["Mike","Matt","Nancy","Adam","Jenny","Nancy","Carl"];
b = {};
for (var i = 0; i < a.length; i++) {
    b[a[i]] = a[i];
}
arr = [];
for (var key in b) {
    arr.push(key);
}

It is a data dictionary that when the key already exists the value is simply overwritten and thus avoiding redundancy, because the key is always unique in data dictionaries. Then the array is filled with the values contained in the previously filled dictionary.

Source: https://stackoverflow.com/a/9229784

  • 1

    Explain what the code is doing, and in case you copied it from somewhere else, at least cite the source.

  • In my opinion, he helped, and we have more patience with those who have now entered the SOPT ...

  • @Venatci, it was very helpful your reply showed a trivial way, please if you have the source put and credit, to enrich your answer, and I have no negative points

  • I located the source and inserted it, but I think an explanation of how it works would make the answer more complete. Don’t want to add?

  • What if the array is integer? I think this technique doesn’t work.

2

The most performative way is to convert the vector into a dictionary, and then convert to vector again.

function Foo (vetor) {
    var dicionario = {};
    for (var i = 0; i < vetor.length; i++) {
        dicionario[vetor[i] + ""] = true;
    }
    var novoVetor = [];
    for (var chave in dicionario) {
        novoVetor.push(chave);
    }
    return novoVetor;
}

This technique avoids wasting time searching the array. You simply write each value in the dictionary - and if a certain value repeats n times, it will be overwritten n - 1 times.

Note that the value true in the dictionary keys is only an arbitrary value. It could be 0, 1, and believe that in most cases even null will work, since we will ignore this value and only care about the key ;)

Editing: I just saw that my answer is just a more verbiage version of Venatci’s answer. Kudos to him.

2

I think it’s worth leaving one third alternative, part of the project PHPJS which aims to bring to the JS features present in PHP. In this case, a port of function array_unique():

function array_unique(inputArr) {
  //  discuss at: http://phpjs.org/functions/array_unique/
  // original by: Carlos R. L. Rodrigues (http://www.jsfromhell.com)
  //    input by: duncan
  //    input by: Brett Zamir (http://brett-zamir.me)
  // bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  // bugfixed by: Nate
  // bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  // bugfixed by: Brett Zamir (http://brett-zamir.me)
  // improved by: Michael Grier
  //        note: The second argument, sort_flags is not implemented;
  //        note: also should be sorted (asort?) first according to docs
  //   example 1: array_unique(['Kevin','Kevin','van','Zonneveld','Kevin']);
  //   returns 1: {0: 'Kevin', 2: 'van', 3: 'Zonneveld'}
  //   example 2: array_unique({'a': 'green', 0: 'red', 'b': 'green', 1: 'blue', 2: 'red'});
  //   returns 2: {a: 'green', 0: 'red', 1: 'blue'}

  var key = '',
    tmp_arr2 = {},
    val = '';

  var __array_search = function (needle, haystack) {
    var fkey = '';
    for (fkey in haystack) {
      if (haystack.hasOwnProperty(fkey)) {
        if ((haystack[fkey] + '') === (needle + '')) {
          return fkey;
        }
      }
    }
    return false;
  };

  for (key in inputArr) {
    if (inputArr.hasOwnProperty(key)) {
      val = inputArr[key];
      if (false === __array_search(val, tmp_arr2)) {
        tmp_arr2[key] = val;
      }
    }
  }

  return tmp_arr2;
}

0

I don’t have a lot of experience with programming and I started to migrate from Java to JS and with that I think I brought the cursed inheritance of verbosity in the code, I have no notion of the performance of this algorithm below, but it worked to solve an exercise here.

function limpaValoresRepetidos(array){
    for(let i in array){ 
        let valorComparado = array[i]    
        let cont = 0         //contador de incidencia de repeticao, seu valor deve ser 1
        for(let i in array){
            if(valorComparado === array[i]){
                cont +=1
                if(cont > 1){
                    cont --
                    delete array[i]
                }
            }
        }
    }
    return array
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.