This question is similar to this one Jquery filter array of object with loop but this time I need to do the filter with an array of objects.
Exemple:
I have
You can put a couple of array methods to use here - filter and some. They're available in all recent browsers, and there are polyfills available for the older browsers.
const myArray = [{ userid: "100", projectid: "10", rowid: "0" }, { userid: "101", projectid: "11", rowid: "1"}, { userid: "102", projectid: "12", rowid: "2" }, { userid: "103", projectid: "13", rowid: "3" }, { userid: "101", projectid: "10", rowid: "4" }];
const myFilter = [{ userid: "101", projectid: "11" }, { userid: "102", projectid: "12" }, { userid: "103", projectid: "11"}];
const myArrayFiltered = myArray.filter((el) => {
return myFilter.some((f) => {
return f.userid === el.userid && f.projectid === el.projectid;
});
});
console.log(myArrayFiltered);
This code will match with not only by userid and projectid but with all properties of myFilter[j].
var filtered = myArray.filter(function(i){
return myFilter.some(function(j){
return !Object.keys(j).some(function(prop){
return i[prop] != j[prop];
});
});
});
console.log(filtered);
So you can use
myFilter = [
{
projectid: "11"
},
{
userid: "101"
},
{
userid: "103",
projectid: "13",
rowid: "3"
}
];
Will return
[ { userid: '101', projectid: '11', rowid: '1' },
{ userid: '103', projectid: '13', rowid: '3' },
{ userid: '101', projectid: '10', rowid: '4' } ]
Wich means all elements with
(projectid=="11")
OR (userid=="101")
OR ( (userid=="103") AND (projectid=="13") AND (rowid=="3") )
You need to loop over your first array, and inside this loop, loop again inside the filter.
If userid and projectid are equals, you can add the row to your filtered array:
myArray = [{
userid: "100",
projectid: "10",
rowid: "0"
}, {
userid: "101",
projectid: "11",
rowid: "1"
}, {
userid: "102",
projectid: "12",
rowid: "2"
}, {
userid: "103",
projectid: "13",
rowid: "3"
}, {
userid: "101",
projectid: "10",
rowid: "4"
}];
myFilter = [{
userid: "101",
projectid: "11"
}, {
userid: "102",
projectid: "12"
}, {
userid: "103",
projectid: "11"
}];
function filterArray(array, filter) {
var myArrayFiltered = [];
for (var i = 0; i < array.length; i++) {
for (var j = 0; j < filter.length; j++) {
if (array[i].userid === filter[j].userid && array[i].projectid === filter[j].projectid) {
myArrayFiltered.push(array[i]);
}
}
}
return myArrayFiltered;
}
myArrayFiltered = filterArray(myArray, myFilter);
console.log(myArrayFiltered);
JSFIDDLE
With Ecma script 6.
const myArrayFiltered = myArray.filter( el => {
return myfilter.some( f => {
return f.userid === el.userid && f.projectid === el.projectid;
});
});
Function:
const filterObjectArray = (arr, filterArr) => (
arr.filter( el =>
filterArr.some( f =>
f.userid === el.userid && f.projectid === el.projectid
)
)
);
console.log(filterObjectArray(myArray, myFilter))
Link to example
If at all a filter like this is required I would propose to create a dictionary (object) whose key is hash of attributes which defines a match (in this case userid & projectid) that way you need to iterate over 1st dict(haystack) to check if key is available in 2nd dict (needle). Hope this helps.
In response to Andy answer above, which I believe should be marked now as answer., if you are looking for exact opposite behavior, use every with negation, something like this.
const result = masterData.filter(ad =>
filterData.every(fd => fd.userid !== md.userid));
result
contains all masterData
except filterData
.