web-dev-qa-db-fra.com

Comment créer un tableau avec des éléments uniques (c.-à-d. Supprimer les doublons)?

J'ai ce code:

var ar = [10,7,8,3,4,7,6];

function isin(n,a){
  for (var i=0;i<a.length;i++){
    if (a[i]== n) {
      var b = true;
      return b;
    } else {
      var c = false;
      return c;
   }
  }
}

function unique(a){
  var arr = [];
  for (var i=0;i<a.length;i++){
    if (!isin(a[i],arr)){
      arr.Push(a[i]);
    }
  }

 return arr;
}

alert(unique(ar));

Dans ce code, j'essaie de créer un nouveau tableau unique (sans doublons) à partir de celui d'origine . Mais j'obtiens toujours le tableau d'origine! Où est mon erreur?

26
DrStrangeLove

L'utilisation d'un tableau simple et le renvoi des clés d'un tableau associatif (contenant uniquement les valeurs "uniques" d'un tableau donné) sont plus efficaces:

function ArrNoDupe(a) {
    var temp = {};
    for (var i = 0; i < a.length; i++)
        temp[a[i]] = true;
    var r = [];
    for (var k in temp)
        r.Push(k);
    return r;
}

$(document).ready(function() {
    var arr = [10, 7, 8, 3, 4, 3, 7, 6];
    var noDupes = ArrNoDupe(arr);
    $("#before").html("Before: " + arr.join(", "));
    $("#after").html("After: " + noDupes.join(", "));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="before"></div>
<div id="after"></div>

Remarque: La fonction ne conserve pas l'ordre des éléments. Si c'est important, utilisez une logique différente.

À partir d'IE9 et de tous les autres navigateurs modernes (par exemple, Chrome, Firefox), cela peut devenir encore plus efficace en utilisant la méthode Object.keys():

function ArrNoDupe(a) {
    var temp = {};
    for (var i = 0; i < a.length; i++)
        temp[a[i]] = true;
    return Object.keys(temp);
}

$(document).ready(function() {
    var arr = [10, 7, 8, 3, 4, 3, 7, 6];
    var noDupes = ArrNoDupe(arr);
    $("#before").html("Before: " + arr.join(", "));
    $("#after").html("After: " + noDupes.join(", "));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="before"></div>
<div id="after"></div>

Merci wateriswet pour ce qui a attiré mon attention . :)

47
Shadow Wizard

Ou pour ceux qui recherchent un one-liner (simple et fonctionnel):

var a = ["1", "1", "2", "3", "3", "1"];
var unique = a.filter(function(item, i, ar){ return ar.indexOf(item) === i; });
56
Josh Mc

Vous pouvez utiliser le nouvel objet natif new Set(list) dans ES6/ES2015 . (c’est-à-dire Babel, TypeScript ou ceux qui ont la chance que tous les navigateurs cibles prennent en charge ES2015).

// I never use this, because it's an iterator, not an array
let s = new Set(list);

ou, si vous souhaitez enchaîner des assistants de tableau, utilisez le nouvel opérateur de propagation ... dans ES6/ES2015 pour le diffuser dans un tableau:

const unique = (list) => {
  return [...new Set(list)];
}

Vous avez besoin d'un tableau pour chaîner des méthodes telles que sort():

const convertText = (textToConvert) => {
  let list = unique(textToConvert.split(/\r?\n/g))
    .sort() // this will error if using uniqueAsIterator() version...
    .filter(x => x != "NULL");
  return list;
}
11
yzorg

Edit: notez l'avertissement de Daniel . Compte tenu de cela et de ce que disent les médecins officiels (ci-dessous), utiliser ce n’est peut-être pas une bonne idée après tout!


Si vous utilisez jQuery, sa fonction unique() fait ceci:

var ar = [1, 2, 1, 2, 2, 3];    
ar = $.unique(ar);
console.log(ar);  // [3, 2, 1] 

La documentation dit:

Notez que cela ne fonctionne que sur les tableaux d’éléments DOM, pas de chaînes ni Nombres.

... mais quand j’ai testé cela avec jQuery 1.9.1, fonctionne aussi pour les chaînes et les nombres. Quoi qu'il en soit, vérifiez que cela fonctionne, surtout si vous utilisez jQuery plus ancien. 

8
Jonik

En plus de l’utilisation de filtre répond par Josh Mc, vous pouvez le rendre plus court dans es6 avec la fonction de flèche

const a = ["1", "1", "2", "3", "3", "1"];
let unique = a.filter((it, i, ar) => ar.indexOf(it) === i);
// unique = [1, 2, 3]
8
Burak Tokak

Parce que votre méthode isin renvoie true ou false après avoir examiné le premier élément.

changez cela en ceci:

function isin(n,a){
  for (var i=0;i<a.length;i++){
    if (a[i]== n){
    return true;

    }
  }
  return false;
}
3
Jamiec

Et avec un peu de plaisir ES5 ...

function uniqueArray(array) {
    var temp = array.reduce(function(previous, current) {
        previous[current] = true;
        return previous;
    }, {});

    return Object.keys(temp);
}

3
theGecko

Vous devriez utiliser indexOf au lieu de votre fonction isIn:

function unique(a){
  var arr = [];
  for (var i=0;i<a.length;i++){
    if ( arr.indexOf(a[i]) == -1){
        arr.Push(a[i]);
    }
}
2
F-A

Je sais que je suis un peu en retard pour répondre à cela. Mais aucune des réponses n'a ce que je ferais. J'aime utiliser l'épissure pour ce genre de chose. Voici un script très simple qui fera exactement ce dont vous avez besoin:

function unique(originalArray){
    var ar = originalArray.slice(0);//Make a copy of the array and store it in ar
    var i = ar.length;
    while(i--){  //Iterate through the array
        if(ar.indexOf(ar[i],i+1)>-1){  //If the array has a duplicate
            ar.splice(i,1);  //Remove that element!
        }
    }
    return ar; //Return the new, more unique array
}
1
Joe Thomas

La façon dont je l'ai fait était d'utiliser le tableau "à l'envers", donc quand j'appuie dessus, j'utilise la clé au lieu de la valeur, comme ceci:

var arr = [];
$('input[type=checkbox]', SearchResults).each( function() {
    if( $(this).is(':checked') )
        arr[ $(this).data('client_id') ] = true;
}

Ensuite, je regarde les clés plutôt que les valeurs.

1
david_nash

Où est mon erreur ??

Ici:

... else {
      var c = false;
      return c;
   }

La fonction isin est définie sur false si n ne correspond pas à le premier élément du tableau. Le corps de la boucle retournera toujours une valeur avant de passer à l'élément suivant.

Supprimez la clause else et déplacez return false au bas de la méthode:

function isin(n,a){
    for (var i=0;i<a.length;i++) {
        if (a[i] == n)
            return true;

    return false;
}

Notez que la méthode isin peut être implémentée immédiatement (ou même remplacée par) un appel à indexOf.

1
aioobe

J'ai fait une recherche similaire, j'ai trouvé cette réponse vraiment bonne:

Valeurs uniques dans un tableau [duplicate]

Vous pouvez réutiliser ces fonctions sur un autre code . C'est également une bonne approche si elle est compatible avec de nombreux navigateurs.

Acclamation.

0
Strawhero

Basé sur la réponse acceptée . Voici un équivalent de CoffeeScript:

unique = (a) ->
  temp = {}
  for i in [0...a.length]
    temp[a[i]] = true
  r = []
  for k of temp
    r.Push(k)
  return r
0
Daniel