我想基于filterArray返回最后两个对象,因为filterArray包含'Orange'作为标签和'Fruit'作为类型。但是因为我所有的obj都包含一个标签数组,所以这个函数包含的标签不能工作。(仅当值标记为字符串时有效)。
const filterArray = [
{ type: 'type', value: ['Fruit'] },
{ type: 'tags', value: ['Apple', 'Orange', 'Peach'] },
]
const obj = [
{ type: 'Sweet Fruit', tags: ['Apple'] },
{ type: 'Fruit', tags: ['Orange', 'Watermelon'] },
{ type: 'Fruit', tags: ['Orange'] },
]
const Newresult = obj.filter(item =>
filterArray.every(({ type, value }) => value.includes(item[type])),
)
console.log(Newresult)
如果const对象为const对象,则此函数有效。Tags不是数组,而是字符串。
您可以使用以下命令:
// use a set in the filter so lookups happen in O(1)
const filter = [
{ type: "type", value: new Set(["Fruit"]) },
{ type: "tags", value: new Set(["Apple", "Orange", "Peach"]) },
];
const obj = [
{ type: "Sweet Fruit", tags: ["Apple"] },
{ type: "Fruit", tags: ["Orange", "Watermelon"] },
{ type: "Fruit", tags: ["Orange"] },
];
const Newresult = obj.filter((item) => (
filter.every(({ type, value }) => {
// check whether the value we want to filter by is an arry
if(Array.isArray(item[type])){
// yes, we are dealing with an array => check if any of the filter criteria are matched
// if you want to check for all criteria use "every()" instead of "some"
return item[type].some(valueInArray => value.has(valueInArray));
}
// if we are not dealing with an array we need to just check one value
return value.has(item[type]);
})
));
console.log(Newresult);
方法的关键变化:
- 我检查我是否正在处理一个数组,如果我做了,我检查数组中的任何值是否在过滤器 提供的白名单值内
- 我使用
Set
而不是数组,这减少了从数组查找O(n)
到0(1)
的时间,因此大大加快了算法。
您可以将data的每个值视为数组,并检查数据是否包含来自过滤器的值。
const
filter = [{ type: 'type', value: ['Fruit'] }, { type: 'tags', value: ['Apple', 'Orange', 'Peach'] }],
data = [{ type: 'Sweet Fruit', tags: ['Apple'] }, { type: 'Fruit', tags: ['Orange', 'Watermelon'] }, { type: 'Fruit', tags: ['Orange'] }, ],
result = data.filter(o => filter.every(({ type, value }) => []
.concat(o[type])
.some(v => value.includes(v))
));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }