Un altro approccio indicizzato in grado di elaborare un numero qualsiasi di matrici contemporaneamente:
// 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;
};
Funziona solo per valori che possono essere valutati come stringhe e dovresti passarli come array come:
intersect ([arr1, arr2, arr3...]);
... ma accetta in modo trasparente oggetti come parametro o come uno qualsiasi degli elementi da intersecare (restituendo sempre array di valori comuni). Esempi:
intersect ({foo: [1, 2, 3, 4], bar: {a: 2, j:4}}); // [2, 4]
intersect ([{x: "hello", y: "world"}, ["hello", "user"]]); // ["hello"]
EDIT: Ho appena notato che questo è, in un certo senso, leggermente difettoso.
Cioè: l'ho codificato pensando che le matrici di input non possano contenere di per sé ripetizioni (come nell'esempio fornito non).
Ma se le matrici di input contengono ripetizioni, ciò produrrebbe risultati errati. Esempio (utilizzando l'implementazione di seguito):
intersect ([[1, 3, 4, 6, 3], [1, 8, 99]]);
// Expected: [ '1' ]
// Actual: [ '1', '3' ]
Fortunatamente questo è facile da risolvere semplicemente aggiungendo l'indicizzazione di secondo livello. Questo è:
Modificare:
if (index[v] === undefined) index[v] = 0;
index[v]++;
di:
if (index[v] === undefined) index[v] = {};
index[v][i] = true; // Mark as present in i input.
...e:
if (index[i] == arrLength) retv.push(i);
di:
if (Object.keys(index[i]).length == arrLength) retv.push(i);
Esempio completo:
// 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' ]