555 votes

Le moyen le plus simple de trouver des valeurs en double dans un tableau JavaScript

J'ai besoin de vérifier un tableau JavaScript pour voir s'il y a des valeurs en double. Quelle est la meilleure façon de le faire? J'ai juste besoin de trouver ce que les valeurs dupliquées sont - je n'ai pas vraiment besoin de leur index ou combien de fois ils sont dupliqués.

Je sais que je peux parcourir le tableau et vérifier toutes les autres valeurs pour un match, mais il semble qu'il devrait y avoir un moyen plus facile. Des idées? Merci!

Connexes: Supprimer les Doublons dans le Tableau JavaScript

374voto

swilliams Points 19415

Vous pouvez trier le tableau, puis le parcourir et voir si l'index suivant (ou précédent) est le même que le courant. En supposant que votre algorithme de tri est bon, cela devrait être inférieur à O (n 2 ):

 var arr = [9, 9, 111, 2, 3, 4, 4, 5, 7];
var sorted_arr = arr.sort(); // You can define the comparing function here. 
                             // JS by default uses a crappy string compare.
var results = [];
for (var i = 0; i < arr.length - 1; i++) {
    if (sorted_arr[i + 1] == sorted_arr[i]) {
        results.push(sorted_arr[i]);
    }
}

alert(results);
 

215voto

Raphael Montanaro Points 1385

Si vous voulez éliminer les doublons, essayez cette solution géniale:

 function eliminateDuplicates(arr) {
  var i,
      len=arr.length,
      out=[],
      obj={};

  for (i=0;i<len;i++) {
    obj[arr[i]]=0;
  }
  for (i in obj) {
    out.push(i);
  }
  return out;
}
 

C'est l'un des meilleurs extraits de code pour JavaScript que j'ai vu. L'original est publié ici: http://dreaminginjavascript.wordpress.com/2008/08/22/eliminating-duplicates/

208voto

Christian Landgren Points 1127

Voici ma réponse du fil dupliqué (!):

Je suis fatigué de voir tous les mauvais exemples avec des boucles ou jQuery. Javascript a les outils parfaits pour cela de nos jours: trier, cartographier et réduire.

Uniq réduit tout en conservant l'ordre existant

 var names = ["Mike","Matt","Nancy","Adam","Jenny","Nancy","Carl"];

var uniq = names.reduce(function(a,b){
    if (a.indexOf(b) < 0 ) a.push(b);
    return a;
  },[]);

console.log(uniq, names) // [ 'Mike', 'Matt', 'Nancy', 'Adam', 'Jenny', 'Carl' ]

// one liner
return names.reduce(function(a,b){if(a.indexOf(b)<0)a.push(b);return a;},[]);
 

Uniq plus rapide avec tri

Il y a probablement des moyens plus rapides mais celui-ci est assez décent.

 var uniq = names.slice() // slice makes copy of array before sorting it
  .sort(function(a,b){
    return a - b;
  })
  .reduce(function(a,b){
    if (a.slice(-1)[0] !== b) a.push(b); // slice(-1)[0] means last item in array without removing it (like .pop())
    return a;
  },[]); // this empty array becomes the starting value for a

// one liner
return names.slice().sort(function(a,b){return a - b}).reduce(function(a,b){if (a.slice(-1)[0] !== b) a.push(b);return a;},[]);
 

31voto

karim79 Points 178055

Vous pouvez ajouter cette fonction, ou la modifier et l'ajouter au prototype Array de Javascript:

 Array.prototype.unique = function () {
    var r = new Array();
    o:for(var i = 0, n = this.length; i < n; i++)
    {
    	for(var x = 0, y = r.length; x < y; x++)
    	{
    		if(r[x]==this[i])
    		{
                alert('this is a DUPE!');
    			continue o;
    		}
    	}
    	r[r.length] = this[i];
    }
    return r;
}

var arr = [1,2,2,3,3,4,5,6,2,3,7,8,5,9];
var unique = arr.unique();
alert(unique);
 

28voto

benvie Points 6181

Mise à JOUR: Les utilisations suivantes optimiser une stratégie combinée. Il optimise primitive recherches pour bénéficier de hachage O(1) recherche (s' unique sur un tableau de primitives est O(n)). L'objet des recherches sont optimisés par le marquage des objets avec un id unique lors de l'itération à travers ce qu'ainsi, l'identification des objets en double est également en O(1) par article et O(n) pour l'ensemble de la liste. La seule exception est les éléments qui sont gelés, mais que ceux qui sont rares et de secours est assurée à l'aide d'un tableau et indexOf.

var unique = function(){
  var hasOwn = {}.hasOwnProperty,
      toString = {}.toString,
      uids = {};

  function uid(){
    var key = Math.random().toString(36).slice(2);
    return key in uids ? uid() : uids[key] = key;
  }

  function unique(array){
    var strings = {}, numbers = {}, others = {},
        tagged = [], failed = [],
        count = 0, i = array.length,
        item, type;

    var id = uid();

    while (i--) {
      item = array[i];
      type = typeof item;
      if (item == null || type !== 'object' && type !== 'function') {
        // primitive
        switch (type) {
          case 'string': strings[item] = true; break;
          case 'number': numbers[item] = true; break;
          default: others[item] = item; break;
        }
      } else {
        // object
        if (!hasOwn.call(item, id)) {
          try {
            item[id] = true;
            tagged[count++] = item;
          } catch (e){
            if (failed.indexOf(item) === -1)
              failed[failed.length] = item;
          }
        }
      }
    }

    // remove the tags
    while (count--)
      delete tagged[count][id];

    tagged = tagged.concat(failed);
    count = tagged.length;

    // append primitives to results
    for (i in strings)
      if (hasOwn.call(strings, i))
        tagged[count++] = i;

    for (i in numbers)
      if (hasOwn.call(numbers, i))
        tagged[count++] = +i;

    for (i in others)
      if (hasOwn.call(others, i))
        tagged[count++] = others[i];

    return tagged;
  }

  return unique;
}();

Si vous avez ES6 Collections, il y a beaucoup plus simple et beaucoup plus rapide version. (shim pour IE9+ et les autres navigateurs ici: https://github.com/Benvie/ES6-Harmony-Collections-Shim)

function unique(array){
  var seen = new Set;
  return array.filter(function(item){
    if (!seen.has(item)) {
      seen.add(item);
      return true;
    }
  });
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X