333 votes

Array.push() si n'existe pas ?

Comment puis-je pousser dans un tableau si aucune des valeurs n'existe? Voici mon tableau :

[
    { name: "tom", text: "tasty" },
    { name: "tom", text: "tasty" },
    { name: "tom", text: "tasty" },
    { name: "tom", text: "tasty" },
    { name: "tom", text: "tasty" }
]

Si j'essaie de pousser à nouveau dans le tableau avec soit name: "tom" ou text: "tasty", je ne veux rien se produire... mais si aucune de ces valeurs n'y est alors je veux que cela exécute .push()

Comment puis-je faire cela?

11 votes

Utilisez un dictionnaire (hachage/arbre) au lieu d'un tableau.

0 votes

Tous ces éléments sont-ils disponibles en javascript ?

0 votes

126voto

Darin Dimitrov Points 528142

Vous pouvez étendre le prototype Array avec une méthode personnalisée:

// vérifier si un élément existe dans un tableau en utilisant une fonction de comparaison
// comparer : function(currentElement)
Array.prototype.inArray = function(comparer) { 
    for(var i=0; i < this.length; i++) { 
        if(comparer(this[i])) return true; 
    }
    return false; 
}; 

// ajoute un élément au tableau s'il n'existe pas déjà en utilisant un comparateur 
// de fonction
Array.prototype.pushIfNotExist = function(element, comparer) { 
    if (!this.inArray(comparer)) {
        this.push(element);
    }
}; 

var array = [{ name: "tom", text: "tasty" }];
var element = { name: "tom", text: "tasty" };
array.pushIfNotExist(element, function(e) { 
    return e.name === element.name && e.text === element.text; 
});

5 votes

Je pense que votre camparer (comparateur ?) devrait prendre deux arguments, cela simplifierait le cas où la valeur ajoutée est en ligne et non dans une variable à laquelle vous pouvez accéder dans votre fonction. array.pushIfNotExist({ name: "tom", text: "tasty" }, function(a,b){ return a.name === b.name && a.text === b.text; });

37 votes

Je me demande pourquoi ce n'est pas natif dans le langage - oubliez comment c'est implémenté - l'idée d '« ajouter seulement si unique » est si fondamentale qu'elle est censée exister.

12 votes

Il est préférable d'étendre le prototype Array avec la méthode IndexOf de JavaScript 1.6 au lieu de votre inArray.

43voto

MistereeDevlord Points 278

http://api.jquery.com/jQuery.unique/

var cleanArray = $.unique(clutteredArray);

vous pourriez également être intéressé par makeArray

L'exemple précédent est le mieux en disant de vérifier s'il existe avant de pousser. Je vois avec du recul qu'il indique également que vous pouvez le déclarer comme faisant partie du prototype (je suppose que c'est aussi appelé Extension de Classe), donc pas de grande amélioration ci-dessous.

Sauf que je ne suis pas sûr si indexOf est plus rapide que inArray ? probablement.

Array.prototype.pushUnique = function (item){
    if(this.indexOf(item) == -1) {
    //if(jQuery.inArray(item, this) == -1) {
        this.push(item);
        return true;
    }
    return false;
}

22 votes

À partir du lien jQuery : Notez que cela ne fonctionne que sur des tableaux d'éléments du DOM, pas sur des chaînes de caractères ou des nombres. De plus, indexOf ne fonctionne pas dans IE8 :(

0 votes

Vous pourriez utiliser lodash _.indexOf, cela fonctionnera dans IE8

26voto

Ronen Rabinovici Points 413

Utilisez une bibliothèque js comme underscore.js pour ces raisons précisément. Utilisez : union: Calcule l'union des tableaux passés en paramètre : la liste des éléments uniques, dans l'ordre, présents dans un ou plusieurs des tableaux.

_.union([1, 2, 3], [101, 2, 1, 10], [2, 1]);
=> [1, 2, 3, 101, 10]

8 votes

Notez que cela renvoie un nouveau tableau et n'ajoute pas réellement à un tableau existant.

4 votes

IMHO il n'y a vraiment pas besoin d'introduire un framework pour tester quelque chose d'aussi simple

1voto

Thomas Eding Points 8651

Utilisez un dictionnaire (hash/arbre) à la place d'un tableau.

-2voto

jgroenen Points 954

Vous pouvez utiliser jQuery grep et push en l'absence de résultats : http://api.jquery.com/jQuery.grep/

C'est essentiellement la même solution que dans la solution "étendre le prototype", mais sans étendre (ou polluer) le prototype.

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