Obtenir toutes les valeurs uniques dans un tableau JavaScript (supprimer les doublons)

J’ai un éventail de chiffres dont je dois m’assurer qu’ils sont uniques. J’ai trouvé l’extrait de code ci-dessous sur Internet et cela fonctionne très bien jusqu’à ce que le tableau contienne un zéro. J’ai trouvé cet autre script ici sur SO qui ressemble presque exactement à cela, mais il n’échoue pas.

Donc, pour m’aider à apprendre, est-ce que quelqu’un peut m’aider à déterminer où le script prototype se passe mal?

Array.prototype.getUnique = function() { var o = {}, a = [], i, e; for (i = 0; e = this[i]; i++) {o[e] = 1}; for (e in o) {a.push (e)}; return a; } 

Plus de réponses à la question en double:

  • Supprimer les doublons de JavaScript Array

Question similaire:

  • Récupère toutes les valeurs avec plus d’une occurrence (c’est-à-dire non unique) dans un tableau

    Avec JavaScript 1.6 / ECMAScript 5, vous pouvez utiliser la méthode de filter native d’un tableau de la manière suivante pour obtenir un tableau avec des valeurs uniques:

     function onlyUnique(value, index, self) { return self.indexOf(value) === index; } // usage example: var a = ['a', 1, 'a', 2, '1']; var unique = a.filter( onlyUnique ); // returns ['a', 1, 2, '1'] 

    Le filter méthode native passera en boucle dans le tableau et ne laissera que les entrées qui transmettent onlyUnique fonction de rappel onlyUnique .

    onlyUnique vérifie si la valeur donnée est la première. Sinon, il doit s’agir d’un duplicata et ne sera pas copié.

    Cette solution fonctionne sans aucune bibliothèque supplémentaire comme jQuery ou prototype.js.

    Cela fonctionne aussi pour les tableaux avec des types de valeurs mixtes.

    Pour les anciens navigateurs (filter et indexOf vous pouvez trouver des solutions de contournement dans la documentation MDN pour filter et indexOf .

    Si vous souhaitez conserver la dernière occurrence d’une valeur, remplacez simplement indexOf par lastIndexOf .

    Avec ES6, cela pourrait être raccourci à ceci:

     // usage example: var myArray = ['a', 1, 'a', 2, '1']; var unique = myArray.filter((v, i, a) => a.indexOf(v) === i); // unique is ['a', 1, 2, '1'] 

    Merci à Camilo Martin pour son commentaire.

    ES6 possède un object natif Set pour stocker des valeurs uniques. Pour obtenir un tableau avec des valeurs uniques, vous pouvez le faire maintenant:

     var myArray = ['a', 1, 'a', 2, '1']; let unique = [...new Set(myArray)]; // unique is ['a', 1, 2, '1'] 

    Le constructeur de Set prend un object itérable, comme Array, et l’opérateur de propagation transforme le set en Array. Merci à Lukas Liese pour son indice dans le commentaire.

    Réponse mise à jour pour ES6 / ES2015 : En utilisant le kit , la solution sur une seule ligne est la suivante:

     var items = [4,5,4,6,3,4,5,2,23,1,4,4,4] var uniqueItems = Array.from(new Set(items)) 

    Qui retourne

     [4, 5, 6, 3, 2, 23, 1] 

    Comme le suggérait le_m , cela peut également être raccourci en utilisant un opérateur de diffusion , comme

     var uniqueItems = [...new Set(items)] 

    Vous pouvez également utiliser underscore.js .

     console.log(_.uniq([1, 2, 1, 3, 1, 4])); 
      

    Je me rends compte que cette question a déjà plus de 30 réponses. Mais j’ai lu toutes les réponses existantes en premier et fait mes propres recherches.

    Je partage toutes les réponses en 4 solutions possibles:

    1. Utilisez la nouvelle fonctionnalité ES6: [...new Set( [1, 1, 2] )];
    2. Utilisez l’object { } pour éviter les doublons
    3. Utiliser un tableau d’aide [ ]
    4. Utilisez le filter + indexOf

    Voici des exemples de codes trouvés dans les réponses:

    Utilisez la nouvelle fonctionnalité ES6: [...new Set( [1, 1, 2] )];

     function uniqueArray0(array) { var result = Array.from(new Set(array)); return result } 

    Utilisez l’object { } pour éviter les doublons

     function uniqueArray1( ar ) { var j = {}; ar.forEach( function(v) { j[v+ '::' + typeof v] = v; }); return Object.keys(j).map(function(v){ return j[v]; }); } 

    Utiliser un tableau d’aide [ ]

     function uniqueArray2(arr) { var a = []; for (var i=0, l=arr.length; i 

    Utilisez le filter + indexOf

     function uniqueArray3(a) { function onlyUnique(value, index, self) { return self.indexOf(value) === index; } // usage var unique = a.filter( onlyUnique ); // returns ['a', 1, 2, '1'] return unique; } 

    Et je me demandais laquelle est la plus rapide. J'ai fait un échantillon de Google Sheet pour tester les fonctions. Remarque: ECMA 6 n'est pas disponible sur Google Sheets, donc je ne peux pas le tester.

    Voici le résultat des tests: entrer la description de l'image ici

    Je m'attendais à voir ce code utilisant object { } gagner car il utilise le hachage. Je suis donc content que les tests aient montré les meilleurs résultats pour cet algorithme dans Chrome et IE. Merci à @rab pour le code .

    J’ai depuis trouvé une belle méthode qui utilise jQuery

     arr = $.grep(arr, function(v, k){ return $.inArray(v ,arr) === k; }); 

    Note: Ce code a été tiré du poste de poinçon de Paul Irish – J’ai oublié de donner le crédit: P

    One Liner, Pure JavaScript

    Avec la syntaxe ES6

    list = list.filter((x, i, a) => a.indexOf(x) == i)

     x --> item in array i --> index of item a --> array reference, (in this case "list") 

    entrer la description de l'image ici

    Avec la syntaxe ES5

     list = list.filter(function (x, i, a) { return a.indexOf(x) == i; }); 

    Compatibilité du navigateur : IE9 +

    Solution la plus courte avec ES6: [...new Set( [1, 1, 2] )];

    Ou si vous souhaitez modifier le prototype Array (comme dans la question d’origine):

     Array.prototype.getUnique = function() { return [...new Set( [this] )]; }; 

    EcmaScript 6 n’est que partiellement implémenté dans les navigateurs modernes (août 2015), mais Babel est devenu très populaire pour le transfert de ES6 (et même d’ES7) vers ES5. De cette façon, vous pouvez écrire du code ES6 dès aujourd’hui!

    Si vous vous demandez ce que le ... signifie, il s’appelle l’ opérateur de propagation . De MDN : «L’opérateur de spread permet à une expression d’être développée dans des endroits où plusieurs arguments (pour les appels de fonction) ou plusieurs éléments (pour les littéraux de tableau) sont attendus». Dans la mesure où un ensemble est itérable (et ne peut avoir que des valeurs uniques), l’opérateur de propagation développera l’ensemble pour remplir le tableau.

    Ressources pour apprendre ES6:

    • Exploration de l’ES6 par le Dr Axel Rauschmayer
    • Rechercher «ES6» dans les bulletins hebdomadaires de JS
    • ES6 en profondeur des articles du blog Mozilla Hacks

    Solution la plus simple:

     var arr = [1, 3, 4, 1, 2, 1, 3, 3, 4, 1]; console.log([...new Set(arr)]); 

    La manière la plus simple et la plus rapide (en Chrome) de le faire:

     Array.prototype.unique = function() { var a = []; for (var i=0, l=this.length; i 

    Parcourt simplement chaque élément du tableau, vérifie si cet élément est déjà dans la liste et, dans le cas contraire, pousse le tableau renvoyé.

    Selon jsPerf, cette fonction est la plus rapide de toutes celles que je puisse trouver - n'hésitez pas à append la vôtre.

    La version non prototype:

     function uniques(arr) { var a = []; for (var i=0, l=arr.length; i 

    Tri

    Lorsque vous devez également sortinger le tableau, le plus rapide est le suivant:

     Array.prototype.sortUnique = function() { this.sort(); var last_i; for (var i=0;i 

    ou non-prototype:

     function sortUnique(arr) { arr.sort(); var last_i; for (var i=0;i 

    Ceci est également plus rapide que la méthode ci-dessus dans la plupart des navigateurs sans chrome.

    PERFORMANCE UNIQUEMENT! ce code est probablement 10 fois plus rapide que tous les codes ici * fonctionne sur tous les navigateurs et a également le plus faible impact sur la mémoire …. et plus encore

    Si vous n’avez pas besoin de réutiliser l’ancien tableau, btw effectue les autres opérations nécessaires avant de le convertir en unique. C’est probablement le moyen le plus rapide d’y parvenir, même très court.

     var array=[1,2,3,4,5,6,7,8,9,0,1,2,1]; 

    alors vous pouvez essayer ceci

     var array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 1]; function toUnique(a, b, c) { //array,placeholder,placeholder b = a.length; while (c = --b) while (c--) a[b] !== a[c] || a.splice(c, 1); return a // not needed ;) } console.log(toUnique(array)); //[3, 4, 5, 6, 7, 8, 9, 0, 2, 1] 

    Beaucoup de réponses ici peuvent ne pas être utiles aux débutants. Si le démultiplication d’un tableau est difficile, connaîtra-t-il vraiment la chaîne prototype, ou même jQuery?

    Dans les navigateurs modernes, une solution propre et simple consiste à stocker des données dans un ensemble conçu pour constituer une liste de valeurs uniques.

     const cars = ['Volvo', 'Jeep', 'Volvo', 'Lincoln', 'Lincoln', 'Ford']; const uniqueCars = Array.from(new Set(cars)); 

    Array.from est utile pour convertir le Set back en Array afin d’avoir facilement access à toutes les méthodes (fonctionnalités) impressionnantes des baies. Il y a aussi d’ autres façons de faire la même chose. Mais vous n’avez peut-être pas besoin d’ Array.from , car les Sets offrent de nombreuses fonctionnalités utiles comme forEach .

    Si vous devez prendre en charge l’ancien Internet Explorer, et donc ne pouvez pas utiliser Set, une technique simple consiste à copier des éléments sur un nouveau tableau tout en vérifiant au préalable s’ils sont déjà dans le nouveau tableau.

     // Create a list of cars, with duplicates. var cars = ['Volvo', 'Jeep', 'Volvo', 'Lincoln', 'Lincoln', 'Ford']; // Create a list of unique cars, to put a car in if we haven't already. var uniqueCars = []; // Go through each car, one at a time. cars.forEach(function (car) { // The code within the following block runs only if the // current car does NOT exist in the uniqueCars list // - aka prevent duplicates if (uniqueCars.indexOf(car) === -1) { // Since we now know we haven't seen this car before, // copy it to the end of the uniqueCars list. uniqueCars.push(car); } }); 

    Pour que cela soit instantanément réutilisable, mettons-le dans une fonction.

     function deduplicate(data) { if (data.length > 0) { var result = []; data.forEach(function (elem) { if (result.indexOf(elem) === -1) { result.push(elem); } }); return result; } } 

    Donc, pour se débarrasser des doublons, nous le ferions maintenant.

     var uniqueCars = deduplicate(cars); 

    La partie deduplicate(cars) devient la chose que nous appelons résultat lorsque la fonction est terminée.

    Il suffit de passer le nom de tout tableau que vous aimez.

    Ce prototype getUnique n’est pas totalement correct, car si j’ai un tableau comme: ["1",1,2,3,4,1,"foo"] il retournera ["1","2","3","4"] et "1" est une chaîne et 1 est un entier; ils sont différents.

    Voici une solution correcte:

     Array.prototype.unique = function(a){ return function(){ return this.filter(a) } }(function(a,b,c){ return c.indexOf(a,b+1) < 0 }); 

    en utilisant:

     var foo; foo = ["1",1,2,3,4,1,"foo"]; foo.unique(); 

    Ce qui précède produira ["1",2,3,4,1,"foo"] .

     ["Defects", "Total", "Days", "City", "Defects"].reduce(function(prev, cur) { return (prev.indexOf(cur) < 0) ? prev.concat([cur]) : prev; }, []); [0,1,2,0,3,2,1,5].reduce(function(prev, cur) { return (prev.indexOf(cur) < 0) ? prev.concat([cur]) : prev; }, []); 

    Sans extension de Array.prototype (c’est une mauvaise pratique) ou en utilisant jquery / underscore, vous pouvez simplement filter le tableau.

    En gardant la dernière occurrence:

      function arrayLastUnique(array) { return array.filter(function (a, b, c) { // keeps last occurrence return c.indexOf(a, b + 1) < 0; }); }, 

    ou première occurrence:

      function arrayFirstUnique(array) { return array.filter(function (a, b, c) { // keeps first occurrence return c.indexOf(a) === b; }); }, 

    Eh bien, ce n'est que javascript ECMAScript 5+, ce qui signifie seulement IE9 +, mais c'est bien pour un développement en HTML / JS natif (Windows Store App, Firefox OS, Sencha, Phonegap, Titanium, ...).

    C’est parce que 0 est une valeur de falsification en JavaScript.

    this[i] sera faux si la valeur du tableau est 0 ou toute autre valeur de falsy.

    Si vous utilisez le framework Prototype, vous n’avez pas besoin de faire des boucles «for», vous pouvez utiliser http://www.prototypejs.org/api/array/uniq comme ceci:

     var a = Array.uniq(); 

    Qui produira un tableau en double sans doublons. Je suis tombé sur votre question en cherchant une méthode pour compter les enregistrements de tableaux distincts, donc après

    uniq ()

    j’ai utilisé

    Taille()

    et il y avait mon résultat simple. ps Désolé si j’ai mal écrit quelque chose

    edit: si vous voulez échapper des enregistrements non définis, vous pouvez append

    compact()

    avant, comme ceci:

     var a = Array.compact().uniq(); 
     Array.prototype.getUnique = function() { var o = {}, a = [] for (var i = 0; i < this.length; i++) o[this[i]] = 1 for (var e in o) a.push(e) return a } 

    Je ne sais pas pourquoi Gabriel Silveira a écrit la fonction de cette façon, mais une forme plus simple qui fonctionne pour moi tout aussi bien et sans minification est:

     Array.prototype.unique = function() { return this.filter(function(value, index, array) { return array.indexOf(value, index + 1) < 0; }); }; 

    ou en CoffeeScript:

     Array.prototype.unique = -> this.filter( (value, index, array) -> array.indexOf(value, index + 1) < 0 ) 

    avec es6 (et maintient l’ordre):

     [...new Set(myArray)]; 

    Créez un ensemble du tableau, puis initialisez une copie superficielle de l’ensemble dans le conteneur souhaité.

     let array = [1,2,3,2,1]; let uniqueArray = [... new Set(array)]; 

    Du blog de Shamasis Bhattacharya (complexité temporelle O (2n)):

     Array.prototype.unique = function() { var o = {}, i, l = this.length, r = []; for(i=0; i 

    Du blog de Paul Irish : amélioration sur JQuery .unique() :

     (function($){ var _old = $.unique; $.unique = function(arr){ // do the default behavior only if we got an array of elements if (!!arr[0].nodeType){ return _old.apply(this,arguments); } else { // reduce the array to contain no dupes via grep/inArray return $.grep(arr,function(v,k){ return $.inArray(v,arr) === k; }); } }; })(jQuery); // in use.. var arr = ['first',7,true,2,7,true,'last','last']; $.unique(arr); // ["first", 7, true, 2, "last"] var arr = [1,2,3,4,5,4,3,2,1]; $.unique(arr); // [1, 2, 3, 4, 5] 

    Recherche de valeurs de tableau uniques dans une méthode simple

     function arrUnique(a){ var t = []; for(var x = 0; x < a.length; x++){ if(t.indexOf(a[x]) == -1)t.push(a[x]); } return t; } arrUnique([1,4,2,7,1,5,9,2,4,7,2]) // [1, 4, 2, 7, 5, 9] 

    Pour résoudre le problème à l’inverse, il peut être utile de ne pas avoir de doublon lorsque vous chargez votre tableau, comme le ferait l’object Set, mais il n’est pas encore disponible dans tous les navigateurs. Cela économise de la mémoire et est plus efficace si vous devez regarder son contenu plusieurs fois.

     Array.prototype.add = function (elem) { if (this.indexOf(elem) == -1) { this.push(elem); } } 

    Échantillon:

     set = []; [1,3,4,1,2,1,3,3,4,1].forEach(function(x) { set.add(x); }); 

    Vous donne set = [1,3,4,2]

    étrange cela n’a pas été suggéré auparavant .. pour supprimer les doublons par clé d’object ( id ci-dessous) dans un tableau, vous pouvez faire quelque chose comme ceci:

     const uniqArray = array.filter((obj, idx, arr) => ( arr.findIndex((o) => o.id === obj.id) === idx )) 

    Il existe un moyen simple de résoudre cette tâche via ES6 – en utilisant Set:

     let arr = [1, 1, 2, 2, 3, 3]; let deduped = [...new Set(arr)] // [1, 2, 3] 

    Vous pouvez également utiliser jQuery

     var a = [1,5,1,6,4,5,2,5,4,3,1,2,6,6,3,3,2,4]; // note: jQuery's filter params are opposite of javascript's native implementation :( var unique = $.makeArray($(a).filter(function(i,itm){ // note: 'index', not 'indexOf' return i == $(a).index(itm); })); // unique: [1, 5, 6, 4, 2, 3] 

    A l’origine répondu à: jQuery fonction pour obtenir tous les éléments uniques d’un tableau?

    Si quelqu’un utilise knockoutjs

     ko.utils.arrayGetDistinctValues() 

    BTW ont regardé tous les utilitaires ko.utils.array* .

    J’ai trouvé que la sérialisation de leur clé de hachage m’a aidé à faire fonctionner ceci pour des objects.

     Array.prototype.getUnique = function() { var hash = {}, result = [], key; for ( var i = 0, l = this.length; i < l; ++i ) { key = JSON.stringify(this[i]); if ( !hash.hasOwnProperty(key) ) { hash[key] = true; result.push(this[i]); } } return result; } 

    Vous pouvez également utiliser sugar.js:

     [1,2,2,3,1].unique() // => [1,2,3] [{id:5, name:"Jay"}, {id:6, name:"Jay"}, {id: 5, name:"Jay"}].unique('id') // => [{id:5, name:"Jay"}, {id:6, name:"Jay"}] 

    Nous pouvons le faire en utilisant des ensembles ES6:

     var duplicatedArray = [1,2,3,4,5,1,1,1,2,3,4]; var uniqueArray = Array.from(new Set(duplicatedArray)); 

    // La sortie sera

     uniqueArray = [1,2,3,4,5];