Une autre approche indexée capable de traiter n'importe quel nombre de tableaux à la fois:
// Calculate intersection of multiple array or object values.
function intersect (arrList) {
var arrLength = Object.keys(arrList).length;
// (Also accepts regular objects as input)
var index = {};
for (var i in arrList) {
for (var j in arrList[i]) {
var v = arrList[i][j];
if (index[v] === undefined) index[v] = 0;
index[v]++;
};
};
var retv = [];
for (var i in index) {
if (index[i] == arrLength) retv.push(i);
};
return retv;
};
Cela ne fonctionne que pour les valeurs qui peuvent être évaluées en tant que chaînes et vous devez les passer sous forme de tableau comme:
intersect ([arr1, arr2, arr3...]);
... mais il accepte de manière transparente les objets comme paramètre ou comme l'un des éléments à recouper (renvoyant toujours un tableau de valeurs communes). Exemples:
intersect ({foo: [1, 2, 3, 4], bar: {a: 2, j:4}}); // [2, 4]
intersect ([{x: "hello", y: "world"}, ["hello", "user"]]); // ["hello"]
EDIT: Je viens de remarquer que c'est, en quelque sorte, légèrement buggé.
C'est-à-dire: je l'ai codé en pensant que les tableaux d'entrée ne peuvent pas contenir de répétitions (comme l'exemple fourni ne le fait pas).
Mais si les tableaux d'entrée contiennent des répétitions, cela produira des résultats erronés. Exemple (en utilisant l'implémentation ci-dessous):
intersect ([[1, 3, 4, 6, 3], [1, 8, 99]]);
// Expected: [ '1' ]
// Actual: [ '1', '3' ]
Heureusement, cela est facile à résoudre en ajoutant simplement une indexation de second niveau. C'est:
Changement:
if (index[v] === undefined) index[v] = 0;
index[v]++;
par:
if (index[v] === undefined) index[v] = {};
index[v][i] = true; // Mark as present in i input.
...et:
if (index[i] == arrLength) retv.push(i);
par:
if (Object.keys(index[i]).length == arrLength) retv.push(i);
Exemple complet:
// Calculate intersection of multiple array or object values.
function intersect (arrList) {
var arrLength = Object.keys(arrList).length;
// (Also accepts regular objects as input)
var index = {};
for (var i in arrList) {
for (var j in arrList[i]) {
var v = arrList[i][j];
if (index[v] === undefined) index[v] = {};
index[v][i] = true; // Mark as present in i input.
};
};
var retv = [];
for (var i in index) {
if (Object.keys(index[i]).length == arrLength) retv.push(i);
};
return retv;
};
intersect ([[1, 3, 4, 6, 3], [1, 8, 99]]); // [ '1' ]