4 回答
 
                    
                    TA贡献1801条经验 获得超16个赞
像这样的东西是清晰、简洁和可维护的。
const filteredItems = response.filter(e => {
const validations = {
containsCategory: category && category.includes(e.category),
containsPrice: prices && prices.includes(e.price),
containsName: names && names.includes(e.name),
};
return Object.values(validations).every(v => v);
});
您可以在此处使用对象,以便获得命名验证的好处以及能够迭代它们并检查每个validation === true. 如果您将每个验证定义为一个变量,那么您有重复的代码。例如
const filteredItems = response.filter(e => {
const containsCategory = category && category.includes(e.category);
const containsPrice = prices && prices.includes(e.price);
const containsName = names && names.includes(e.name);
return containsName && containsPrice && containsName;
});
每次要添加验证时,都必须在两个地方(返回和定义)更新名称。
重要的是要注意,虽然有更简洁的方法可以使用您发布的代码实现相同的结果,但这允许您在将来轻松添加更多验证类别 - 而更简洁的解决方案则不能。
例如,您可以轻松地添加字符串过滤器或高级过滤器功能validations:
const validations = {
matchesSearchString: !searchString || e.name.toLowerCase().startsWith(searchSting.toLowerCase()),
isAnAncientQueen: isAnAncientQueen(e.name),
/* -- snip -- */
};
 
                    
                    TA贡献1936条经验 获得超7个赞
我想说其他答案更简洁,但是如果您可以利用 TypeScript 的类型系统来制作一个安全且非常通用的解决方案。这种方法是否更可取取决于您在类型安全性和可维护性方面的确切需求。
我的通用方法是定义一个可以应用于任何对象的过滤器类型,然后实现一个知道如何将过滤器应用于任意类型数组的函数。
对于“过滤器”,这将起作用:
type Filter<T> = {
[P in keyof T]?: (T[P])[]
}
您可以将其理解为“对于Ttype的每个成员X,将有一个可选的同名Filter<T>类型数组。X[]
那么过滤函数就变成了:
function filter<T>(items: T[], filter: Filter<T>): T[]{
// interim result for easier debugging
let result =
items.filter(
item => {
// check each member in the filter
for (let key in filter) {
let valueInFilter = filter[key];
// if it's empty, then it's OK
if (valueInFilter) {
// otherwise the value on item MUST be found in the array on filter
let valueInItem = item[key];
if (valueInFilter.indexOf(valueInItem) == -1) {
return false;
}
}
}
// if every check passes, keep the item
return true;
}
);
return result;
}
把它们放在一起,它看起来像这样:
let responses: IResponse[] = [
{ "id": 1, "name": "Alise", "price": 400, "category": 4 },
{ "id": 2, "name": "Bob", "price": 300, "category": 2 }
];
let someFilter: Filter<IResponse> = {
id: [1, 2, 4],
price: [300]
};
console.log(filter(responses, someFilter))
我把它放在TypeScript Playground上,所以你可以看到所有类型检查都有效。
 
                    
                    TA贡献1829条经验 获得超7个赞
你可以做Array.prototype.filter()满足AND条件Array.prototype.every()和OR条件Array.prototype.some():
const response = [{"id": 1, "name": "Alise", "price": 400, "category": 4},{id:2, name:'Megan', price:300, category:2}],
name = ["Jessy", "Megan"],
price = [300, 500],
category = [1,2,4],
filters = {name,price,category},
result = response.filter(o => Object
.entries(filters)
.every(([key,values]) =>
!values.length || values.some(value => o[key] == value)
)
)
console.log(result)
与Array.prototype.includes()基于 - 的方法相比,当(如果)您需要非严格匹配(例如,对某些关键字不区分大小写的部分匹配)时,它可能会更好地缩放
 
                    
                    TA贡献1815条经验 获得超13个赞
您可以获取键和值并检查includes并检查对象的所有过滤器功能。
let
filter = ([key, values]) => o => !values.length || values.includes(o[key]),
constraints = {
id: [], // empty - take all values
name: ["Jessy", "Megan"],
price: [300, 500],
category: [1, 2, 4]
}
filters = Object.entries(constraints).map(filter),
response = [{ id: 1, name: "Alise", price: 400, category: 4 }, { id: 2, name: "Megan", price: 300, category: 4 }],
result = response.filter(o => filters.every(fn => fn(o)));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
添加回答
举报
