使用多个过滤条件过滤对象数组
Filtering an array of objects with multiple filter conditions
假设我有一个对象数组:
let users = [{
name: "Mark",
location: "US",
job: "engineer"
},
{
name: "Mark",
location: "US",
job: "clerk"
},
{
name: "Angela",
location: "Europe",
job: "pilot"
},
{
name: "Matthew",
location: "US",
job: "engineer"
}]
我有一个过滤器对象,其中包含我要过滤数据的所有类别(每个键可以有多个值):
const filters = {
name: ["Mark", "Matthew"],
location: ["US"],
job: ["Engineer"]
}
根据这些过滤器和数据,预期结果为 return:
[{name: "Mark", location: "US", job: "Engineer"}, {name: "Matthew", location: "US", job: "Engineer"}]
我尝试过过滤:
users.filter(user => {
for(let k in filters) {
if(user[k] === filters[k]) {
return true;
}
}
})
但是,此方法没有考虑到过滤器类别可能包含多个值,我可以通过以下方式处理这些值:
filters[k][0] or filters[k][1]
但它不是动态的。
如果有人有任何意见,我们将不胜感激!谢谢。
在 filters
上使用 Object.entries()
以获得 [key, values]
对的数组。用 Array.every()
迭代对,并检查每个对是否包含当前对象的值。
const fn = (arr, filters) => {
const filtersArr = Object.entries(filters)
return arr.filter(o =>
filtersArr.every(([key, values]) =>
values.includes(o[key])
)
)
}
const users = [{"name":"Mark","location":"US","job":"engineer"},{"name":"Mark","location":"US","job":"clerk"},{"name":"Angela","location":"Europe","job":"pilot"},{"name":"Matthew","location":"US","job":"engineer"}]
const filters = {
name: ["Mark", "Matthew"],
location: ["US"],
job: ["engineer"]
}
const result = fn(users, filters)
console.log(result)
使用 Array.includes()
的一个警告是大小写的差异会提供 false
答案(Engineer 和 engineer 在这种情况下)。要解决此问题,请使用不区分大小写的搜索标志 (i
) 将当前单词转换为 RegExp,并使用 Array.some()
检查它是否适合数组中的任何单词。
const fn = (arr, filters) => {
const filtersArr = Object.entries(filters)
return arr.filter(o =>
filtersArr.every(([key, values]) => {
const pattern = new RegExp(`^${o[key]}$`, 'i')
return values.some(v => pattern.test(v))
})
)
}
const users = [{"name":"Mark","location":"US","job":"engineer"},{"name":"Mark","location":"US","job":"clerk"},{"name":"Angela","location":"Europe","job":"pilot"},{"name":"Matthew","location":"US","job":"engineer"}]
const filters = {
name: ["Mark", "Matthew"],
location: ["US"],
job: ["Engineer"]
}
const result = fn(users, filters)
console.log(result)
您可以遍历过滤器对象的条目并确保每个键的值都是允许的值之一。
let users = [{name:"Mark",location:"US",job:"Engineer"},{name:"Mark",location:"US",job:"clerk"},{name:"Angela",location:"Europe",job:"pilot"},{name:"Matthew",location:"US",job:"Engineer"}];
const filters = {
name: ["Mark", "Matthew"],
location: ["US"],
job: ["Engineer"]
};
const res = users.filter(o =>
Object.entries(filters).every(([k,v])=>v.includes(o[k])));
console.log(res);
假设我有一个对象数组:
let users = [{
name: "Mark",
location: "US",
job: "engineer"
},
{
name: "Mark",
location: "US",
job: "clerk"
},
{
name: "Angela",
location: "Europe",
job: "pilot"
},
{
name: "Matthew",
location: "US",
job: "engineer"
}]
我有一个过滤器对象,其中包含我要过滤数据的所有类别(每个键可以有多个值):
const filters = {
name: ["Mark", "Matthew"],
location: ["US"],
job: ["Engineer"]
}
根据这些过滤器和数据,预期结果为 return:
[{name: "Mark", location: "US", job: "Engineer"}, {name: "Matthew", location: "US", job: "Engineer"}]
我尝试过过滤:
users.filter(user => {
for(let k in filters) {
if(user[k] === filters[k]) {
return true;
}
}
})
但是,此方法没有考虑到过滤器类别可能包含多个值,我可以通过以下方式处理这些值:
filters[k][0] or filters[k][1]
但它不是动态的。
如果有人有任何意见,我们将不胜感激!谢谢。
在 filters
上使用 Object.entries()
以获得 [key, values]
对的数组。用 Array.every()
迭代对,并检查每个对是否包含当前对象的值。
const fn = (arr, filters) => {
const filtersArr = Object.entries(filters)
return arr.filter(o =>
filtersArr.every(([key, values]) =>
values.includes(o[key])
)
)
}
const users = [{"name":"Mark","location":"US","job":"engineer"},{"name":"Mark","location":"US","job":"clerk"},{"name":"Angela","location":"Europe","job":"pilot"},{"name":"Matthew","location":"US","job":"engineer"}]
const filters = {
name: ["Mark", "Matthew"],
location: ["US"],
job: ["engineer"]
}
const result = fn(users, filters)
console.log(result)
使用 Array.includes()
的一个警告是大小写的差异会提供 false
答案(Engineer 和 engineer 在这种情况下)。要解决此问题,请使用不区分大小写的搜索标志 (i
) 将当前单词转换为 RegExp,并使用 Array.some()
检查它是否适合数组中的任何单词。
const fn = (arr, filters) => {
const filtersArr = Object.entries(filters)
return arr.filter(o =>
filtersArr.every(([key, values]) => {
const pattern = new RegExp(`^${o[key]}$`, 'i')
return values.some(v => pattern.test(v))
})
)
}
const users = [{"name":"Mark","location":"US","job":"engineer"},{"name":"Mark","location":"US","job":"clerk"},{"name":"Angela","location":"Europe","job":"pilot"},{"name":"Matthew","location":"US","job":"engineer"}]
const filters = {
name: ["Mark", "Matthew"],
location: ["US"],
job: ["Engineer"]
}
const result = fn(users, filters)
console.log(result)
您可以遍历过滤器对象的条目并确保每个键的值都是允许的值之一。
let users = [{name:"Mark",location:"US",job:"Engineer"},{name:"Mark",location:"US",job:"clerk"},{name:"Angela",location:"Europe",job:"pilot"},{name:"Matthew",location:"US",job:"Engineer"}];
const filters = {
name: ["Mark", "Matthew"],
location: ["US"],
job: ["Engineer"]
};
const res = users.filter(o =>
Object.entries(filters).every(([k,v])=>v.includes(o[k])));
console.log(res);