我有一个具有两个字段filter1
和filter2
的对象,其值形式为数组
let filter = {filter1:["mine","your"]: filter2:["C","D"]}
//不固定
数据是对象数组的形式
let data = [
{ id:1, filter1:["mine"], filter2:["E","C"]},
{ id:2, filter1:["mine"], filter2:["E","C","F"]},
{ id:3, filter1:["your"], filter2:["C"]},
{ id:3, filter1:["your"], filter2:["D","C"]},
{ id:5, filter1:["other"], filter2:["F"]},
...
]
我必须过滤掉那些具有特定键中存在的任何一个字段的对象例如,如果filter
是{filter1:["mine"]: filter2:["F","D"]}
,它将首先在数据对象的filter1中搜索filter1的任何元素,然后在数据对象的filter2中搜索filter2的任何元素,如果找到任何一个,则返回该对象
few example
result for{filter1:["mine"]: filter2:["F","D"]}
result = [
{ id:1, filter1:["mine"], filter2:["E","C"]}, //since filter1 "mine"
{ id:2, filter1:["mine"], filter2:["E","C","F"]}, //since filter1 "mine"
{ id:3, filter1:["your"], filter2:["D","C"]}, //since from "F" and "D" from filter2 "D" is present
{ id:5, filter1:["other"], filter2:["F"]}, //since "F" from filter2 is present
]
result for{filter1:["your"]: filter2:["F","G"]}
result = [
{ id:2, filter1:["mine"], filter2:["E","C","F"]}, //since "F" from filter2 is present
{ id:3, filter1:["your"], filter2:["D","C"]}, //since filter1 is "your"
{ id:5, filter1:["other"], filter2:["F"]}, //since "F" from filter2 is present
]
result for{filter1:[]: filter2:["D"]}
result = [
{ id:3, filter1:["your"], filter2:["D","C"]}, //since filter2 has "D"
]
您可以使用.filter()
,.some()
和.includes()
的组合:
const data = [
{ id:1, filter1:["mine"], filter2:["E","C"]},
{ id:2, filter1:["mine"], filter2:["E","C","F"]},
{ id:3, filter1:["your"], filter2:["C"]},
{ id:3, filter1:["your"], filter2:["D","C"]},
{ id:5, filter1:["other"], filter2:["F"]}
];
const search = ({ filter1, filter2 }) =>
data.filter(item =>
item.filter1.some(fItem => filter1.includes(fItem)) ||
item.filter2.some(fItem => filter2.includes(fItem))
);
const result = search({ filter1:["mine"], filter2:["F","D"] });
console.log(result);
您可以推广RoMilton提出的解决方案,通过在传递的过滤器对象的Object.entries()
上调用some()
,然后用嵌套的some()
调用迭代每个key
和filter_array
。
如果你也Array#concat()
当前迭代的数据元素属性到一个数组,你可以包括非数组属性在过滤器对象,如id
在这种情况下。
const data = [
{ id: 1, filter1: ["mine"], filter2: ["E", "C"] },
{ id: 2, filter1: ["mine"], filter2: ["E", "C", "F"] },
{ id: 3, filter1: ["your"], filter2: ["C"] },
{ id: 3, filter1: ["your"], filter2: ["D", "C"] },
{ id: 5, filter1: ["other"], filter2: ["F"] }
];
const search = (array, filter_object) =>
array.filter(item =>
Object.entries(filter_object).some(([key, filter_array]) =>
[].concat(item[key]).some(fitem => filter_array.includes(fitem)))
);
const filter = { filter1: ["mine"], filter2: ["F", "D"] };
const result = search(data, filter);
console.log(...result.map(({ id }) => ({ id })));
const filter2 = { id: [5], filter1: ["mine"] }
const result2 = search(data, filter2);
console.log(...result2.map(({ id }) => ({ id })));
.as-console-wrapper { max-height: 100% !important; top: 0; }
concat()
的这种用法也可以应用于硬编码解决方案,以允许在数据数组中可能不是数组的属性。
const data = [
{ id: 1, filter1: "mine", filter2: ["E", "C"] },
{ id: 2, filter1: ["mine"], filter2: ["E", "C", "F"] },
{ id: 3, filter1: ["your"], filter2: ["C"] },
{ id: 3, filter1: ["your"], filter2: ["D", "C"] },
{ id: 5, filter1: ["other"], filter2: ["F"] }
];
const search = ({ filter1, filter2 }) => (
data.filter(item =>
[].concat(item.filter1).some(fItem => filter1.includes(fItem)) ||
[].concat(item.filter2).some(fItem => filter2.includes(fItem))
));
const result = search({ filter1: ["mine"], filter2: ["F", "D"] });
console.log(result);