C'è un modo per restituire la differenza tra due array in JavaScript?
Per esempio:
var a1 = ['a', 'b'];
var a2 = ['a', 'b', 'c', 'd'];
// need ["c", "d"]
O(a1.length x log(a2.length))
- questa prestazione è possibile in JavaScript?
C'è un modo per restituire la differenza tra due array in JavaScript?
Per esempio:
var a1 = ['a', 'b'];
var a2 = ['a', 'b', 'c', 'd'];
// need ["c", "d"]
O(a1.length x log(a2.length))
- questa prestazione è possibile in JavaScript?
Risposte:
Suppongo che stai confrontando un array normale. In caso contrario, è necessario modificare il ciclo for in un ciclo for .. in .
function arr_diff (a1, a2) {
var a = [], diff = [];
for (var i = 0; i < a1.length; i++) {
a[a1[i]] = true;
}
for (var i = 0; i < a2.length; i++) {
if (a[a2[i]]) {
delete a[a2[i]];
} else {
a[a2[i]] = true;
}
}
for (var k in a) {
diff.push(k);
}
return diff;
}
console.log(arr_diff(['a', 'b'], ['a', 'b', 'c', 'd']));
console.log(arr_diff("abcd", "abcde"));
console.log(arr_diff("zxc", "zxc"));
Una soluzione migliore, se non ti interessa la compatibilità con le versioni precedenti, sta usando il filtro. Tuttavia, questa soluzione funziona.
var a1 = ['a', 'b'];
e var a2 = ['a', 'b', 'c', 'd', 'b'];
, restituirà una risposta sbagliata , cioè ['c', 'd', 'b']
invece di ['c', 'd']
.
function diff2(a, b) { var i, la = a.length, lb = b.length, res = []; if (!la) return b; else if (!lb) return a; for (i = 0; i < la; i++) { if (b.indexOf(a[i]) === -1) res.push(a[i]); } for (i = 0; i < lb; i++) { if (a.indexOf(b[i]) === -1) res.push(b[i]); } return res; }
Esiste un modo migliore con ES7:
Intersezione
let intersection = arr1.filter(x => arr2.includes(x));
Perché [1,2,3] [2,3]
cederà [2,3]
. D'altra parte, perché [1,2,3] [2,3,5]
restituirà la stessa cosa.
Differenza
let difference = arr1.filter(x => !arr2.includes(x));
Perché [1,2,3] [2,3]
cederà [1]
. D'altra parte, perché [1,2,3] [2,3,5]
restituirà la stessa cosa.
Per una differenza simmetrica , puoi fare:
let difference = arr1
.filter(x => !arr2.includes(x))
.concat(arr2.filter(x => !arr1.includes(x)));
In questo modo, otterrai una matrice contenente tutti gli elementi di arr1 che non sono in arr2 e viceversa
Come ha sottolineato @Joshaven Potter nella sua risposta, puoi aggiungerlo ad Array.prototype in modo che possa essere usato in questo modo:
Array.prototype.diff = function(arr2) { return this.filter(x => !arr2.includes(x)); }
[1, 2, 3].diff([2, 3])
< 0
invece di== -1
Array
differenza è un cosiddetto set operation
, perché la ricerca di proprietà è il lavoro proprio di Set
s, che sono ordini di grandezza più veloci di indexOf
/ includes
. In poche parole, la tua soluzione è molto inefficiente e piuttosto lenta.
Set
, i valori devono essere unici, no?
[1,2,3] [2,3,5]
dato che i numeri sono unici, ma se avessi detto [1,1,2,3] [1,2,3,5]
e previsto [1]
che non avresti potuto usare Set
. La tua soluzione non funzionerebbe però: - / Ho finito per creare questa funzione perché non riuscivo a trovare un modo soddisfacente per farlo in modo più succinto. Se hai qualche idea su come farlo, mi piacerebbe saperlo!
Array.includes()
ES7 non è la funzione invece di ES6? (1) (2) - e per continuare, con ES6 potresti usare Array.some()
ad es let intersection = aArray.filter(a => bArray.some(b => a === b))
. No?
Array.prototype.diff = function(a) {
return this.filter(function(i) {return a.indexOf(i) < 0;});
};
////////////////////
// Examples
////////////////////
[1,2,3,4,5,6].diff( [3,4,5] );
// => [1, 2, 6]
["test1", "test2","test3","test4","test5","test6"].diff(["test1","test2","test3","test4"]);
// => ["test5", "test6"]
Nota indexOf e il filtro non sono disponibili in ie prima di ie9.
[1,2,3].diff([3,4,5])
verrà restituita [1,2]
invece di [1,2,4,5]
non risolvere il problema nella domanda originale, qualcosa di cui tenere conto.
Questo è di gran lunga il modo più semplice per ottenere esattamente il risultato che stai cercando, usando jQuery:
var diff = $(old_array).not(new_array).get();
diff
ora contiene ciò che era in old_array
quello che non è innew_array
.not
con un array, jQuery utilizza l'utilità integrata.grep()
specifica per filtrare gli array. Non riesco a vederlo cambiare.
Il metodo di differenza in Underscore (o nella sua sostituzione drop-in, Lo-Dash ) può fare anche questo:
(R)eturns the values from array that are not present in the other arrays
_.difference([1, 2, 3, 4, 5], [5, 2, 10]);
=> [1, 3, 4]
Come con qualsiasi funzione Underscore, puoi anche usarlo in uno stile più orientato agli oggetti:
_([1, 2, 3, 4, 5]).difference([5, 2, 10]);
Esistono due possibili interpretazioni per "differenza". Ti lascio scegliere quale vuoi. Dì che hai:
var a1 = ['a', 'b' ];
var a2 = [ 'b', 'c'];
Se vuoi ottenere ['a']
, usa questa funzione:
function difference(a1, a2) {
var result = [];
for (var i = 0; i < a1.length; i++) {
if (a2.indexOf(a1[i]) === -1) {
result.push(a1[i]);
}
}
return result;
}
Se vuoi ottenere ['a', 'c']
(tutti gli elementi contenuti in una a1
o a2
, ma non in entrambe, la cosiddetta differenza simmetrica ), usa questa funzione:
function symmetricDifference(a1, a2) {
var result = [];
for (var i = 0; i < a1.length; i++) {
if (a2.indexOf(a1[i]) === -1) {
result.push(a1[i]);
}
}
for (i = 0; i < a2.length; i++) {
if (a1.indexOf(a2[i]) === -1) {
result.push(a2[i]);
}
}
return result;
}
Se stai usando lodash, puoi usare _.difference(a1, a2)
(caso 1 sopra) o _.xor(a1, a2)
(caso 2).
Se si utilizza Underscore.js, è possibile utilizzare _.difference(a1, a2)
funzione per il caso 1.
Il codice sopra funziona su tutti i browser. Tuttavia, per array di grandi dimensioni con oltre 10.000 articoli, diventa piuttosto lento, poiché presenta una complessità O (n²). Su molti browser moderni, possiamo sfruttare l' Set
oggetto ES6 per accelerare le cose. Lodash utilizza automaticamente Set
quando è disponibile. Se non stai usando lodash, usa la seguente implementazione, ispirata al post sul blog di Axel Rauschmayer :
function difference(a1, a2) {
var a2Set = new Set(a2);
return a1.filter(function(x) { return !a2Set.has(x); });
}
function symmetricDifference(a1, a2) {
return difference(a1, a2).concat(difference(a2, a1));
}
Il comportamento di tutti gli esempi può essere sorprendente o non ovvio se ti interessa di -0, +0, NaN o array sparsi. (Per la maggior parte degli usi, questo non ha importanza.)
Per ottenere la differenza simmetrica è necessario confrontare le matrici in entrambi i modi (o in tutti i modi in caso di più matrici)
// diff between just two arrays:
function arrayDiff(a, b) {
return [
...a.filter(x => !b.includes(x)),
...b.filter(x => !a.includes(x))
];
}
// diff between multiple arrays:
function arrayDiff(...arrays) {
return [].concat(...arrays.map( (arr, i) => {
const others = arrays.slice(0);
others.splice(i, 1);
const unique = [...new Set([].concat(...others))];
return arr.filter(x => !unique.includes(x));
}));
}
// diff between just two arrays:
function arrayDiff(a, b) {
return [
...a.filter(x => b.indexOf(x) === -1),
...b.filter(x => a.indexOf(x) === -1)
];
}
// diff between multiple arrays:
function arrayDiff(...arrays) {
return [].concat(...arrays.map( (arr, i) => {
const others = arrays.slice(0);
others.splice(i, 1);
const unique = [...new Set([].concat(...others))];
return arr.filter(x => unique.indexOf(x) === -1);
}));
}
// diff between just two arrays:
function arrayDiff(a, b) {
var arrays = Array.prototype.slice.call(arguments);
var diff = [];
arrays.forEach(function(arr, i) {
var other = i === 1 ? a : b;
arr.forEach(function(x) {
if (other.indexOf(x) === -1) {
diff.push(x);
}
});
})
return diff;
}
// diff between multiple arrays:
function arrayDiff() {
var arrays = Array.prototype.slice.call(arguments);
var diff = [];
arrays.forEach(function(arr, i) {
var others = arrays.slice(0);
others.splice(i, 1);
var otherValues = Array.prototype.concat.apply([], others);
var unique = otherValues.filter(function (x, j) {
return otherValues.indexOf(x) === j;
});
diff = diff.concat(arr.filter(x => unique.indexOf(x) === -1));
});
return diff;
}
Esempio:
// diff between two arrays:
const a = ['a', 'd', 'e'];
const b = ['a', 'b', 'c', 'd'];
arrayDiff(a, b); // (3) ["e", "b", "c"]
// diff between multiple arrays
const a = ['b', 'c', 'd', 'e', 'g'];
const b = ['a', 'b'];
const c = ['a', 'e', 'f'];
arrayDiff(a, b, c); // (4) ["c", "d", "g", "f"]
function arrayDiffByKey(key, ...arrays) {
return [].concat(...arrays.map( (arr, i) => {
const others = arrays.slice(0);
others.splice(i, 1);
const unique = [...new Set([].concat(...others))];
return arr.filter( x =>
!unique.some(y => x[key] === y[key])
);
}));
}
Esempio:
const a = [{k:1}, {k:2}, {k:3}];
const b = [{k:1}, {k:4}, {k:5}, {k:6}];
const c = [{k:3}, {k:5}, {k:7}];
arrayDiffByKey('k', a, b, c); // (4) [{k:2}, {k:4}, {k:6}, {k:7}]
Un approccio più pulito in ES6 è la seguente soluzione.
var a1 = ['a', 'b'];
var a2 = ['a', 'b', 'c', 'd'];
a2.filter(d => !a1.includes(d)) // gives ["c", "d"]
a2.filter(d => a1.includes(d)) // gives ["a", "b"]
[ ...a2.filter(d => !a1.includes(d)),
...a1.filter(d => !a2.includes(d)) ]
a1 = ['a', 'b', 'e']
: e non verrà estratto.
In questo caso è possibile utilizzare un set . È ottimizzato per questo tipo di operazione (unione, intersezione, differenza).
Assicurati che si applichi al tuo caso, una volta che non consente duplicati.
var a = new JS.Set([1,2,3,4,5,6,7,8,9]);
var b = new JS.Set([2,4,6,8]);
a.difference(b)
// -> Set{1,3,5,7,9}
Set
funzione senza dover ottenere tutto il resto ...
function diff(a1, a2) {
return a1.concat(a2).filter(function(val, index, arr){
return arr.indexOf(val) === arr.lastIndexOf(val);
});
}
Unire entrambi gli array, i valori univoci verranno visualizzati solo una volta, quindi indexOf () sarà uguale a lastIndexOf ().
per sottrarre un array da un altro, usa semplicemente lo snippet di seguito:
var a1 = ['1','2','3','4','6'];
var a2 = ['3','4','5'];
var items = new Array();
items = jQuery.grep(a1,function (item) {
return jQuery.inArray(item, a2) < 0;
});
Restituirà ['1,' 2 ',' 6 '] che sono elementi del primo array che non esistono nel secondo.
Pertanto, in base al tuo esempio di problema, la soluzione esatta è il seguente codice:
var array1 = ["test1", "test2","test3", "test4"];
var array2 = ["test1", "test2","test3","test4", "test5", "test6"];
var _array = new Array();
_array = jQuery.grep(array2, function (item) {
return jQuery.inArray(item, array1) < 0;
});
Con l'arrivo di ES6 con set e operatore splat (al momento di funzionare solo in Firefox, controllare la tabella di compatibilità ), è possibile scrivere una delle seguenti righe:
var a = ['a', 'b', 'c', 'd'];
var b = ['a', 'b'];
var b1 = new Set(b);
var difference = [...new Set([...a].filter(x => !b1.has(x)))];
che si tradurrà in [ "c", "d" ]
.
b.filter(x => !a.indexOf(x)))
O(n + m)
tua soluzione è O(n * m)
dove n e m sono lunghezze di matrici. Prendi lunghe liste e la mia soluzione funzionerà in pochi secondi, mentre la tua richiederà ore.
a.filter(x => !b1.has(x))
è più semplice. E nota la specifica richiede solo la complessità di essere n * f(m) + m
con f(m)
sublineare in media. È meglio di n * m
, ma non necessariamente n + m
.
var difference = [...new Set([...a].filter(x => !b1.has(x)))];
Perché stai creando un array 'a' duplicato? Perché stai trasformando il risultato del filtro in un set e poi di nuovo in un array? Non è equivalente avar difference = a.filter(x => !b1.has(x));
Il calcolo difference
tra due matrici è una delle Set
operazioni. Il termine indica già che è Set
necessario utilizzare il tipo nativo , al fine di aumentare la velocità di ricerca. Ad ogni modo, ci sono tre permutazioni quando si calcola la differenza tra due set:
[+left difference] [-intersection] [-right difference]
[-left difference] [-intersection] [+right difference]
[+left difference] [-intersection] [+right difference]
Ecco una soluzione funzionale che riflette queste permutazioni.
difference
:// small, reusable auxiliary functions
const apply = f => x => f(x);
const flip = f => y => x => f(x) (y);
const createSet = xs => new Set(xs);
const filter = f => xs => xs.filter(apply(f));
// left difference
const differencel = xs => ys => {
const zs = createSet(ys);
return filter(x => zs.has(x)
? false
: true
) (xs);
};
// mock data
const xs = [1,2,2,3,4,5];
const ys = [0,1,2,3,3,3,6,7,8,9];
// run the computation
console.log( differencel(xs) (ys) );
difference
:differencer
è banale. È solo differencel
con argomenti capovolti. Puoi scrivere una funzione per comodità:const differencer = flip(differencel)
. È tutto!
difference
:Ora che abbiamo quello destro e sinistro, anche l'implementazione del simmetrico difference
diventa banale:
// small, reusable auxiliary functions
const apply = f => x => f(x);
const flip = f => y => x => f(x) (y);
const concat = y => xs => xs.concat(y);
const createSet = xs => new Set(xs);
const filter = f => xs => xs.filter(apply(f));
// left difference
const differencel = xs => ys => {
const zs = createSet(ys);
return filter(x => zs.has(x)
? false
: true
) (xs);
};
// symmetric difference
const difference = ys => xs =>
concat(differencel(xs) (ys)) (flip(differencel) (xs) (ys));
// mock data
const xs = [1,2,2,3,4,5];
const ys = [0,1,2,3,3,3,6,7,8,9];
// run the computation
console.log( difference(xs) (ys) );
Immagino che questo esempio sia un buon punto di partenza per avere un'idea del significato della programmazione funzionale:
Programmazione con blocchi predefiniti che possono essere collegati in molti modi diversi.
Una soluzione che indexOf()
verrà utilizzata andrà bene per array di piccole dimensioni, ma man mano che crescono in lunghezza, le prestazioni degli algoritmi si avvicinano O(n^2)
. Ecco una soluzione che funzionerà meglio per array molto grandi usando oggetti come array associativi per memorizzare le voci dell'array come chiavi; elimina automaticamente anche le voci duplicate ma funziona solo con valori stringa (o valori che possono essere archiviati in modo sicuro come stringhe):
function arrayDiff(a1, a2) {
var o1={}, o2={}, diff=[], i, len, k;
for (i=0, len=a1.length; i<len; i++) { o1[a1[i]] = true; }
for (i=0, len=a2.length; i<len; i++) { o2[a2[i]] = true; }
for (k in o1) { if (!(k in o2)) { diff.push(k); } }
for (k in o2) { if (!(k in o1)) { diff.push(k); } }
return diff;
}
var a1 = ['a', 'b'];
var a2 = ['a', 'b', 'c', 'd'];
arrayDiff(a1, a2); // => ['c', 'd']
arrayDiff(a2, a1); // => ['c', 'd']
La risposta sopra di Joshaven Potter è ottima. Ma restituisce elementi nella matrice B che non sono nella matrice C, ma non viceversa. Ad esempio, se var a=[1,2,3,4,5,6].diff( [3,4,5,7]);
quindi genererà: ==> [1,2,6]
, ma no [1,2,6,7]
, che è la differenza effettiva tra i due. Puoi ancora usare il codice di Potter sopra, ma semplicemente ripetere il confronto anche una volta al contrario:
Array.prototype.diff = function(a) {
return this.filter(function(i) {return !(a.indexOf(i) > -1);});
};
////////////////////
// Examples
////////////////////
var a=[1,2,3,4,5,6].diff( [3,4,5,7]);
var b=[3,4,5,7].diff([1,2,3,4,5,6]);
var c=a.concat(b);
console.log(c);
Questo dovrebbe produrre: [ 1, 2, 6, 7 ]
Un altro modo per risolvere il problema
function diffArray(arr1, arr2) {
return arr1.concat(arr2).filter(function (val) {
if (!(arr1.includes(val) && arr2.includes(val)))
return val;
});
}
diffArray([1, 2, 3, 7], [3, 2, 1, 4, 5]); // return [7, 4, 5]
Inoltre, è possibile utilizzare la sintassi della funzione freccia:
const diffArray = (arr1, arr2) => arr1.concat(arr2)
.filter(val => !(arr1.includes(val) && arr2.includes(val)));
diffArray([1, 2, 3, 7], [3, 2, 1, 4, 5]); // return [7, 4, 5]
Array.prototype.difference = function(e) {
return this.filter(function(i) {return e.indexOf(i) < 0;});
};
eg:-
[1,2,3,4,5,6,7].difference( [3,4,5] );
=> [1, 2, 6 , 7]
difference
come funzione in una versione futura e questa funzione ha una firma della funzione diversa dalla tua, si romperà il codice o le librerie esterne che utilizzano questa funzione.
Soluzione molto semplice con la funzione filtro di JavaScript:
var a1 = ['a', 'b'];
var a2 = ['a', 'b', 'c', 'd'];
function diffArray(arr1, arr2) {
var newArr = [];
var myArr = arr1.concat(arr2);
newArr = myArr.filter(function(item){
return arr2.indexOf(item) < 0 || arr1.indexOf(item) < 0;
});
alert(newArr);
}
diffArray(a1, a2);
Cosa ne pensi di questo:
Array.prototype.contains = function(needle){
for (var i=0; i<this.length; i++)
if (this[i] == needle) return true;
return false;
}
Array.prototype.diff = function(compare) {
return this.filter(function(elem) {return !compare.contains(elem);})
}
var a = new Array(1,4,7, 9);
var b = new Array(4, 8, 7);
alert(a.diff(b));
Quindi in questo modo puoi fare array1.diff(array2)
per ottenere la loro differenza (Orribile complessità temporale per l'algoritmo - O (array1.length x array2.length) Credo)
Utilizzando http://phrogz.net/JS/ArraySetMath.js è possibile:
var array1 = ["test1", "test2","test3", "test4"];
var array2 = ["test1", "test2","test3","test4", "test5", "test6"];
var array3 = array2.subtract( array1 );
// ["test5", "test6"]
var array4 = array1.exclusion( array2 );
// ["test5", "test6"]
filter
)fn
Parametro di callback opzionale che consente di specificare come confrontare gli elementi dell'arrayfunction diff(a, b, fn){
var max = Math.max(a.length, b.length);
d = [];
fn = typeof fn === 'function' ? fn : false
for(var i=0; i < max; i++){
var ac = i < a.length ? a[i] : undefined
bc = i < b.length ? b[i] : undefined;
for(var k=0; k < max; k++){
ac = ac === undefined || (k < b.length && (fn ? fn(ac, b[k]) : ac == b[k])) ? undefined : ac;
bc = bc === undefined || (k < a.length && (fn ? fn(bc, a[k]) : bc == a[k])) ? undefined : bc;
if(ac == undefined && bc == undefined) break;
}
ac !== undefined && d.push(ac);
bc !== undefined && d.push(bc);
}
return d;
}
alert(
"Test 1: " +
diff(
[1, 2, 3, 4],
[1, 4, 5, 6, 7]
).join(', ') +
"\nTest 2: " +
diff(
[{id:'a',toString:function(){return this.id}},{id:'b',toString:function(){return this.id}},{id:'c',toString:function(){return this.id}},{id:'d',toString:function(){return this.id}}],
[{id:'a',toString:function(){return this.id}},{id:'e',toString:function(){return this.id}},{id:'f',toString:function(){return this.id}},{id:'d',toString:function(){return this.id}}],
function(a, b){ return a.id == b.id; }
).join(', ')
);
length
valori. È già di proprietà normale. jsperf.com/array-length-caching
Funziona così: fondamentalmente unisci i due array, cerca i duplicati e invia ciò che non è duplicato in un nuovo array che fa la differenza.
function diff(arr1, arr2) {
var newArr = [];
var arr = arr1.concat(arr2);
for (var i in arr){
var f = arr[i];
var t = 0;
for (j=0; j<arr.length; j++){
if(arr[j] === f){
t++;
}
}
if (t === 1){
newArr.push(f);
}
}
return newArr;
}
// approccio es6
function diff(a, b) {
var u = a.slice(); //dup the array
b.map(e => {
if (u.indexOf(e) > -1) delete u[u.indexOf(e)]
else u.push(e) //add non existing item to temp array
})
return u.filter((x) => {return (x != null)}) //flatten result
}
ancora un'altra risposta, ma sembra che nessuno abbia menzionato jsperf in cui confrontano diversi algoritmi e supporto tecnologico: https://jsperf.com/array-difference-javascript sembra che l'uso del filtro ottenga i migliori risultati. Grazie
Solo pensando ... per il bene di una sfida ;-) questo funzionerebbe ... (per array di base di stringhe, numeri, ecc.) Nessun array nidificato
function diffArrays(arr1, arr2, returnUnion){
var ret = [];
var test = {};
var bigArray, smallArray, key;
if(arr1.length >= arr2.length){
bigArray = arr1;
smallArray = arr2;
} else {
bigArray = arr2;
smallArray = arr1;
}
for(var i=0;i<bigArray.length;i++){
key = bigArray[i];
test[key] = true;
}
if(!returnUnion){
//diffing
for(var i=0;i<smallArray.length;i++){
key = smallArray[i];
if(!test[key]){
test[key] = null;
}
}
} else {
//union
for(var i=0;i<smallArray.length;i++){
key = smallArray[i];
if(!test[key]){
test[key] = true;
}
}
}
for(var i in test){
ret.push(i);
}
return ret;
}
array1 = "test1", "test2","test3", "test4", "test7"
array2 = "test1", "test2","test3","test4", "test5", "test6"
diffArray = diffArrays(array1, array2);
//returns ["test5","test6","test7"]
diffArray = diffArrays(array1, array2, true);
//returns ["test1", "test2","test3","test4", "test5", "test6","test7"]
Nota che l'ordinamento probabilmente non sarà come notato sopra ... ma se lo desideri, chiama .sort () sull'array per ordinarlo.
Volevo una funzione simile che includesse un vecchio array e un nuovo array e mi dava un array di oggetti aggiunti e un array di oggetti rimossi, e volevo che fosse efficiente (quindi no. Contiene!).
Puoi giocare con la mia soluzione proposta qui: http://jsbin.com/osewu3/12 .
Qualcuno può vedere eventuali problemi / miglioramenti a tale algoritmo? Grazie!
Elenco dei codici:
function diff(o, n) {
// deal with empty lists
if (o == undefined) o = [];
if (n == undefined) n = [];
// sort both arrays (or this won't work)
o.sort(); n.sort();
// don't compare if either list is empty
if (o.length == 0 || n.length == 0) return {added: n, removed: o};
// declare temporary variables
var op = 0; var np = 0;
var a = []; var r = [];
// compare arrays and add to add or remove lists
while (op < o.length && np < n.length) {
if (o[op] < n[np]) {
// push to diff?
r.push(o[op]);
op++;
}
else if (o[op] > n[np]) {
// push to diff?
a.push(n[np]);
np++;
}
else {
op++;np++;
}
}
// add remaining items
if( np < n.length )
a = a.concat(n.slice(np, n.length));
if( op < o.length )
r = r.concat(o.slice(op, o.length));
return {added: a, removed: r};
}
Stavo cercando una risposta semplice che non implicasse l'uso di librerie diverse, e mi è venuta in mente la mia che non credo sia stata menzionata qui. Non so quanto sia efficiente o altro ma funziona;
function find_diff(arr1, arr2) {
diff = [];
joined = arr1.concat(arr2);
for( i = 0; i <= joined.length; i++ ) {
current = joined[i];
if( joined.indexOf(current) == joined.lastIndexOf(current) ) {
diff.push(current);
}
}
return diff;
}
Per il mio codice ho bisogno di estrarre anche i duplicati, ma suppongo che non sia sempre preferito.
Immagino che il principale svantaggio sia che sta potenzialmente confrontando molte opzioni che sono già state respinte.
soluzione littlebit per la migliore risposta
function arr_diff(a1, a2)
{
var a=[], diff=[];
for(var i=0;i<a1.length;i++)
a[a1[i]]=a1[i];
for(var i=0;i<a2.length;i++)
if(a[a2[i]]) delete a[a2[i]];
else a[a2[i]]=a2[i];
for(var k in a)
diff.push(a[k]);
return diff;
}
questo prenderà in considerazione l'attuale tipo di elemento. b / c quando creiamo un [a1 [i]] converte un valore in stringa dal suo valore originale, quindi abbiamo perso il valore reale.