En incorporant l'idée de Christoph et en supposant quelques méthodes d'itération non standard sur des tableaux et des objets / hachages ( each
et amis), nous pouvons obtenir la différence, l'union et l'intersection en temps linéaire sur environ 20 lignes au total:
var setOPs = {
minusAB : function (a, b) {
var h = {};
b.each(function (v) { h[v] = true; });
return a.filter(function (v) { return !h.hasOwnProperty(v); });
},
unionAB : function (a, b) {
var h = {}, f = function (v) { h[v] = true; };
a.each(f);
b.each(f);
return myUtils.keys(h);
},
intersectAB : function (a, b) {
var h = {};
a.each(function (v) { h[v] = 1; });
b.each(function (v) { h[v] = (h[v] || 0) + 1; });
var fnSel = function (v, count) { return count > 1; };
var fnVal = function (v, c) { return v; };
return myUtils.select(h, fnSel, fnVal);
}
};
Cela suppose que each
et filter
sont définis pour les tableaux, et que nous avons deux méthodes utilitaires:
myUtils.keys(hash)
: retourne un tableau avec les clés du hachage
myUtils.select(hash, fnSelector,
fnEvaluator)
: renvoie un tableau avec les résultats de l'appel fnEvaluator
sur les paires clé / valeur pour lesquelles
fnSelector
renvoie true.
Le select()
est vaguement inspiré par Common Lisp, et est simplement filter()
et map()
roulé en un seul. (Il serait préférable de les définir sur Object.prototype
, mais cela fait des ravages avec jQuery, alors j'ai opté pour des méthodes utilitaires statiques.)
Performance: test avec
var a = [], b = [];
for (var i = 100000; i--; ) {
if (i % 2 !== 0) a.push(i);
if (i % 3 !== 0) b.push(i);
}
donne deux ensembles de 50 000 et 66 666 éléments. Avec ces valeurs, AB prend environ 75 ms, tandis que l'union et l'intersection sont d'environ 150 ms chacune. (Mac Safari 4.0, utilisant la date Javascript pour le timing.)
Je pense que c'est une récompense décente pour 20 lignes de code.