Reputation: 1089
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 an array of objects like this:
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"
}
...]
I want to filter it with an array like this:
myFilter = [
{
userid: "101",
projectid: "11"
},
{
userid: "102",
projectid: "12"
},
{
userid: "103",
projectid: "11"
}]
and return this (the userid and the projectid in myFilter need to match the userid and the projectid in myArray):
myArrayFiltered = [
{
userid: "101",
projectid: "11",
rowid: "1"
},
{
userid: "102",
projectid: "12",
rowid: "2"
}]
How can I do that ?
Upvotes: 77
Views: 125423
Reputation: 128
This worked for me
master.filter(md => child.some(fd => fd.id == md.id));
const master = [{
id: 1,
name: 'Canada'
}, {
id: 2,
name: 'India'
}, {
id: 3,
name: 'USA'
}];
const child = [1, 3]
const filtered = master.filter(m => child.some(c => c == m.id));
console.log('result', filtered);
master.filter(md => child.some(fd => fd.id == md.id));
Upvotes: 0
Reputation: 574
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(md =>
filterData.every(fd => fd.userid !== md.userid));
result
contains all masterData
except filterData
.
Upvotes: 43
Reputation: 9186
based on @Renato his answer, but shorter:
const myArray = [{ userid: "100", projectid: "10", rowid: "0" }, ...];
const myFilter = [{ userid: "101", projectid: "11" }, ...];
const data = myArray.filter((arrayEl) =>
myFilter.some((filterEl) => filterEl.userid === arrayEl.userid && filterEl.projectid === arrayEl.projectid)
);
The myFilter.some
expression checks if there is at least one element in the myFilter
array which has the condition we set (filterEl.userid === arrayEl.userid && filterEl.projectid === arrayEl.projectid
)
If there is one, it returns true
and the myArray.filter
will keep that entry on the resulting array, otherwise, it is filtered.
Upvotes: 17
Reputation: 53
if you need negation for the same
const masterData = [
{
userid: "101",
projectid: "11",
rowid: "1"
},
{
userid: "101",
projectid: "18",
rowid: "1"
},
{
userid: "101",
projectid: "19",
rowid: "1"
},{
userid: "102",
projectid: "12",
rowid: "2"
}, {
userid: "109",
projectid: "10",
rowid: "4"
}];
const filterData = [
{
userid: "101",
projectid: "11"
},
{
userid: "102",
projectid: "12"
},
{
userid: "109",
projectid: "10"
}
];
const myArrayFiltered = masterData.filter(array => filterData.every(filter => (!(filter.userid === array.userid && filter.projectid === array.projectid))));
console.log(myArrayFiltered)
Upvotes: 1
Reputation: 1
var arr1 = [
{ name:'r', type:"t1" },
{ name:'i', type:"t2" },
{ name:'n', type:"t1" }
];
var arr2 = [
{ name:'r', type:"t1" },
{ name:'i', type:"t2" },
{ name:'n', type:"t3" },
];
let output = arr1.filter(x => !arr2.find(y => (y.name == x.name && y.type == x.type)));
console.log(output);
// inverted
output = arr1.filter(x => !!arr2.find(y => (y.name == x.name && y.type == x.type)));
console.log(output);
Upvotes: 0
Reputation: 63514
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);
Upvotes: 147
Reputation: 4335
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))
Upvotes: 25
Reputation: 342
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") )
Upvotes: 6
Reputation: 315
You can use jquery map, this return one array of matches:
var _filter=function(arr_data,arr_filter){
return $.map( arr_data, function( n ) {
for(var f in arr_filter){
if(arr_filter[f].userid == n.userid && arr_filter[f].projectid == n.projectid){
return n;
}
}
});
}
var resp = _filter(myArray,myFilter);
console.log(resp);
Upvotes: 3
Reputation: 26
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.
Upvotes: 1
Reputation: 555
var filtered = [];
for(var arr in myArray){
for(var filter in myFilter){
if(myArray[arr].userid == myFilter[filter].userid && myArray[arr].projectid == myFilter[filter].projectid){
filtered.push(myArray[arr].userid);
}
}
}
console.log(filtered);
Upvotes: 14
Reputation: 4100
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);
Upvotes: 5