I've got two arrays in Javascript which currently look like this, but are updated by HTTP requests (node):
var x = [[292,"2349","902103","9"],[3289,"93829","092","920238"]]
var y = [[292,"2349","902103","9"],[322,"93829","092","920238"],[924,"9320","8932","4329"]]
I'm looking to compare these arrays, so that, if there is an array inside y that is not in x, it will be saved to a new array - z
. Note that sometimes the order of arrays inside the arrays will change, but I would not like this to affect the result.
If there is an array inside x that is not in y, however, is should not be saved to z
.
I read JavaScript array difference and have been able to replicate this, but if the x
array is not shown in y
, it is printed to z
. I am wondering if it is possible for this not to be stored, only the different items in y
?
Use a higher-order function that accepts an array (which changes with each iteration of y
) and returns a new function that operates on each element (nested array) in some
. It returns true
if the arrays contain the same elements regardless of order.
function matches(outer) {
return function (el) {
if (outer.length !== el.length) return false;
return el.every(function (x) {
return outer.indexOf(x) > -1;
});
}
}
Iterate over y
and return a list of arrays that aren't in x
.
function finder(x, y) {
return y.filter(function (el) {
return !x.some(matches(el));
});
}
finder(x, y);
DEMO
You can use this function arrayDiff
.
It takes two arrays (A and B) and returns an array of all elements that are in the first array and not in the second (A \ B), with any duplicates removed. Two array elements are equal if their JSON serialization is the same.
var x = [[292,"2349","902103","9"],[3289,"93829","092","920238"]];
var y = [[292,"2349","902103","9"],[322,"93829","092","920238"],[924,"9320","8932","4329"]];
var z = arrayDiff(y, x);
// z is [[322,"93829","092","920238"],[924,"9320","8932","4329"]]
// arrayDiff :: [a], [a] -> [a]
function arrayDiff(a1, a2) {
let a1Set = toStringSet(a1),
a2Set = toStringSet(a2);
return Array.from(a1Set)
.filter(jsonStr => !a2Set.has(jsonStr))
.map(JSON.parse);
// toStringSet :: [a] -> Set<String>
function toStringSet(arr) {
return new Set(arr.map(JSON.stringify));
}
}
This should work even if the order in the inner arrays is different.
I'm assuming you will have only numbers and strings in there and you don't expect a strict comparison between them.
var x = [[292,"2349","902103","9"],[3289,"93829","092","920238"]];
var y = [[292,"2349","902103","9"],[322,"93829","092","920238"],[924,"9320","8932","4329"]];
// this will do y \ x
var z = arrDiff(y, x);
console.log(z);
function arrDiff(arr1, arr2) {
var rez = [];
for (var i = 0; i < arr1.length; i++) {
if ( ! contains(arr2, arr1[i])) {
rez.push(arr1[i]);
}
}
return rez;
}
function contains(arr, x) {
x = x.slice().sort().toString();
for (var i = 0; i < arr.length; i++) {
// compare current item with the one we are searching for
if (x === arr[i].slice().sort().toString()) {
return true;
}
}
return false;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With