用另一个对象数组过滤对象数组
Posted
技术标签:
【中文标题】用另一个对象数组过滤对象数组【英文标题】:Filter array of objects with another array of objects 【发布时间】:2015-09-09 09:45:27 【问题描述】:这个问题与Jquery filter array of object with loop 类似,但这次我需要对一组对象进行过滤。
示例:
我有一个这样的对象数组:
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"
]
并返回这个(myFilter中的userid和projectid需要匹配myArray中的userid和projectid):
myArrayFiltered = [
userid: "101",
projectid: "11",
rowid: "1"
,
userid: "102",
projectid: "12",
rowid: "2"
]
我该怎么做?
【问题讨论】:
【参考方案1】:您可以在这里使用几个数组方法 - filter
和 some
。它们适用于所有最新的浏览器,并且有适用于旧版浏览器的 polyfill。
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);
【讨论】:
太棒了!比使用 for 循环更好!简洁很多 嗨@Andy,我正在做同样的事情,只是改变not equal to !==
的一个条件,但这不适用于我的情况。那么有没有其他方法可以处理不等于条件?在这里查看我的实时示例:playcode.io/586682
根据您的喜好,您还可以将声明更简洁一点:myArray.filter(el => myFilter.some(f => f.userid === el.userid && f.projectid === el.projectid))
【参考方案2】:
使用 Ecma 脚本 6。
const myArrayFiltered = myArray.filter( el =>
return myfilter.some( f =>
return f.userid === el.userid && f.projectid === el.projectid;
);
);
功能:
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
【讨论】:
【参考方案3】:响应上面的Andy 答案,我认为现在应该将其标记为答案。如果您正在寻找完全相反的行为,请使用带有否定的every,类似这样。
const result = masterData.filter(ad =>
filterData.every(fd => fd.userid !== md.userid));
result
包含 all masterData
except filterData
。
【讨论】:
【参考方案4】: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);
【讨论】:
【参考方案5】:基于@Renato 他的回答,但更短:
const myArray = [ userid: "100", projectid: "10", rowid: "0" , ...];
const myFilter = [ userid: "101", projectid: "11" , ...];
const myArrayFiltered = myArray.filter(array => myFilter.some(filter => filter.userid === array.userid && filter.projectid === array.projectid));
【讨论】:
【参考方案6】:你需要循环你的第一个数组,并在这个循环中,在过滤器中再次循环。
如果 userid 和 projectid 相等,则可以将该行添加到过滤后的数组中:
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
【讨论】:
【参考方案7】:此代码不仅会匹配 userid 和 projectid,还会匹配 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);
所以你可以使用
myFilter = [
projectid: "11"
,
userid: "101"
,
userid: "103",
projectid: "13",
rowid: "3"
];
会回来
[ userid: '101', projectid: '11', rowid: '1' ,
userid: '103', projectid: '13', rowid: '3' ,
userid: '101', projectid: '10', rowid: '4' ]
Wich 表示所有带有
的元素(projectid=="11")
OR (userid=="101")
OR ( (userid=="103") AND (projectid=="13") AND (rowid=="3") )
【讨论】:
【参考方案8】:你可以使用jquery map,这会返回一个匹配数组:
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);
【讨论】:
【参考方案9】:如果需要这样的过滤器,我建议创建一个字典(对象),其键是属性的哈希值,它定义了一个匹配(在本例中为 userid 和 projectid),您需要迭代第一个字典( haystack)检查第二个字典(针)中是否有可用的密钥。 希望这会有所帮助。
【讨论】:
【参考方案10】: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);
【讨论】:
【参考方案11】:如果你需要相同的否定
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)
【讨论】:
以上是关于用另一个对象数组过滤对象数组的主要内容,如果未能解决你的问题,请参考以下文章