Pourvu que j'ai deux collections:
c1 - [{a:1},{a:2},{a:3}]
et
c2 - [{a:1},{a:7},{a:8}]
quel est le moyen le plus rapide d'ajouter des éléments uniques à partir de c2
en c1
en utilisant Underscore.JS
? Les nombres réels dans les collections seraient 2K
pour c1
et 500
pour c2
, l'opération est effectuée souvent, donc doit être performante!
pdate 1 - J'utilise uniquement Underscore.JS
pendant quelques jours, je n'ai pas trouvé de moyen d'ajouter une collection à une autre (je peux filtrer c2
moi-même) - est-ce trivial dans Underscore.JS
?
Ce qui suit:
Notez que cela ne fonctionnerait que si tous vos objets ont la propriété a
.
_.uniq(_.union(c1, c2), false, function(item, key, a){ return item.a; });
Vous pouvez trouver d'autres options dans cette question .
Essayer:
_.uniq(_.union(c1, c2), false, _.property('a'))
En détail:
_.union(*arrays)
Calcule l'union des tableaux passés.
_.property(key)
(depuis la version 1.6.0)
Renvoie une fonction qui renverra elle-même la propriété key de tout objet transmis.
_.uniq(array, [isSorted], [iteratee])
Produit une version sans doublon du tableau, en utilisant
===
Pour tester l'égalité des objets. Si vous savez à l'avance que le tableau est trié, passertrue
pour isSorted exécutera un algorithme beaucoup plus rapide. Si vous souhaitez calculer des éléments uniques en fonction d'une transformation, passez une fonction itérative.
La documentation de la fonction uniq()
mentionne qu'elle s'exécute beaucoup plus rapidement si la liste est triée. L'utilisation des appels chaînés peut également améliorer la lisibilité. Vous pouvez donc faire:
_.chain(c1).union(c2).sortBy("a").uniq(true, function(item){ return item.a; }).value();
Ou si vous préférez la version non chaînée (qui est de 11 caractères plus courte mais moins lisible):
_.uniq(_.sortBy(_.union(c1,c2),"a"),true, function(item){ return item.a; });
La documentation et les exemples de uniq()
ne précisent pas le fonctionnement de la fonction de rappel. L'algorithme de la fonction uniq()
appelle cette fonction sur chaque élément des deux listes. Si le résultat de cette fonction est le même, il supprime cet élément (en supposant qu'il est dupliqué).
union()
empêche en fait les doublons quand il est appelé sur un tableau. Nous pouvons également utiliser ce fait:
_.map(_.union(_.pluck(c1,"a"),_.pluck(c2,"a")),function (item) {return {a:item};});
Ce qui précède comme convertit d'abord la liste des objets en tableaux simples (pluck()
) puis les combine en utilisant union()
et finalement utilise map()
pour faire une liste d'objets.
Référence: niq ()
Puisqu'il y a un grand nombre de propriétés dans les deux objets et que cet algorithme s'exécute souvent, il serait préférable d'utiliser le noyau Javascript au lieu de n'importe quelle bibliothèque:
//adds all new properties from the src to dst. If the property already exists, updates the number in dst. dst and src are objects
function extendNumberSet( dst, src ) {
var allVals = [];
for ( var i = 0; i < dst.length; i++ ) {
allVals.Push(dst[i].a);
}
for ( var i = 0; i < src.length; i++ ) {
if ( allVals.indexOf( src[i].a ) === -1 ) {
dst.Push( src[i] );
}
}
}
voici n JSfiddle pour le tester .