'Array of objects intersection
I have two lists of objects and I would like to filter my array1 without the file key that are in the array2 :
What I did :
array1 = array1.filter(function(n) {
for(var i=0; i < array2.length; i++){
if(n.file != array2[i].file){
return n;
}
}
});
This returns exactly the array1 whereas if I replace != with == it returns the objects I want to get rid of.
I don't understand why.
https://jsfiddle.net/hrzzohnL/1/
So at the end I would like to end with this array :
[
{
"file": "tttt.csv",
"media": "tttt"
}
]
Solution 1:[1]
Using filter and some functions
var array1 = [{ "file": "tttt.csv", "media": "tttt" }, { "file": "bob_bob.csv", "media": "bob_bob" }, { "file": "bob1_bob1.csv", "media": "bob1_bob1" }, ];
var array2 = [{ "title": "bob_bob", "version": "bob", "date": "27/4/2016", "selected": false, "file": "bob_bob.csv", "media": "bob_bob", "exists": true }, { "title": "bob1_bob1", "version": "bob", "date": "27/4/2016", "selected": false, "file": "bob1_bob1.csv", "media": "bob_bob", "exists": true }]
var res = array1.filter(n => !array2.some(n2 => n.file == n2.file));
document.write(JSON.stringify(res));
*solution uses ES6 arrow function, it may not work in old browsers
Solution 2:[2]
Here's a version that uses some built-in array methods make to this easier for you. It uses array.some to return either true (when some or even one element in the array returns true for the test case) or false. Invert that, and you have your filter result. It looks much cleaner!
var array1 = [{"file": "tttt.csv","media": "tttt"},{"file": "bob_bob.csv","media": "bob_bob"},{"file": "bob1_bob1.csv","media": "bob1_bob1"},];
var array2 = [{"title": "bob_bob","version": "bob","date": "27/4/2016","selected": false,"file": "bob_bob.csv","media": "bob_bob","exists": true},{"title": "bob1_bob1","version": "bob","date": "27/4/2016","selected": false,"file": "bob1_bob1.csv","media": "bob_bob","exists": true}]
var result = array1.filter(function(n1) {
return !(array2.some(function(n2){
return n1.file === n2.file;
}))
});
document.write('<pre>' + JSON.stringify(result))
Solution 3:[3]
You could use a temporary object as reference if the file is in the other array.
var array1 = [{ "file": "tttt.csv", "media": "tttt" }, { "file": "bob_bob.csv", "media": "bob_bob" }, { "file": "bob1_bob1.csv", "media": "bob1_bob1" }],
array2 = [{ "title": "bob_bob", "version": "bob", "date": "27/4/2016", "selected": false, "file": "bob_bob.csv", "media": "bob_bob", "exists": true }, { "title": "bob1_bob1", "version": "bob", "date": "27/4/2016", "selected": false, "file": "bob1_bob1.csv", "media": "bob_bob", "exists": true }],
temp = Object.create(null);
array2.forEach(function (a) {
temp[a.file] = true;
});
array1 = array1.filter(function (a) {
return !temp[a.file];
});
document.write('<pre>' + JSON.stringify(array1, 0, 4) + '</pre>');
Solution 4:[4]
in this case array intersection with _id
arraysOfFilterArrays = [array1, array2,array3,array4];
beforeReady = arraysOfFilterArrays.reduce((a, b) => a.filter(a => b.some(b => a.id === b.id)));
console.log(beforeReady);
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | |
| Solution 3 | |
| Solution 4 | AlphaCodeProgrammer |
