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; }
添加回答
舉報