柯里化过滤器将filter逻辑拆为“定规则→喂数据”两步,提升复用性与灵活性;支持eq/gt/includes等操作符,通过filterBy(key)(value)(operator)(data)链式调用,兼顾类型安全与边界处理。

柯里化能帮你把一个通用过滤函数拆成“先定规则、再喂数据”的两步操作,让代码更灵活、复用性更强。
用柯里化封装 filter 逻辑
核心思路是:把数组作为最后一个参数传入,前面的参数(如字段名、比较值、操作符)先固定下来,返回一个等待数组的函数。
- 这样同一个过滤规则可以反复用于不同数据源(比如用户列表、订单列表、日志数组)
- 避免每次调用都重复写
arr.filter(...)和相同的判断逻辑 - 支持组合使用,比如
filterBy('status', 'active')(users)
实现一个通用的柯里化过滤器
下面是一个支持等于、大于、包含等常见操作的柯里化函数:
const createFilter = (key, value, operator = 'eq') => {
return (data) => data.filter(item => {
const itemValue = item[key];
switch (operator) {
case 'eq': return itemValue === value;
case 'gt': return itemValue > value;
case 'includes': return String(itemValue).includes(String(value));
case 'startsWith': return String(itemValue).startsWith(String(value));
default: return false;
}
});
};
// 柯里化版本:支持链式参数传递
const filterBy = (key) => (value) => (operator) => (data) =>
data.filter(item => {
const itemValue = item[key];
switch (operator) {
case 'eq': return itemValue === value;
case 'gt': return itemValue > value;
case 'includes': return String(itemValue).includes(String(value));
default: return false;
}
});
用法示例:
立即学习“Java免费学习笔记(深入)”;
const isActive = filterBy('status')('active')('eq');
const users = [{name: 'Alice', status: 'active'}, {name: 'Bob', status: 'inactive'}];
console.log(isActive(users)); // [{name: 'Alice', status: 'active'}]
const priceAbove100 = filterBy('price')(100)('gt');
const products = [{name: 'A', price: 150}, {name: 'B', price: 80}];
console.log(priceAbove100(products)); // [{name: 'A', price: 150}]
配合高阶函数增强复用性
柯里化之后,很容易和其它函数组合,比如结合 compose 或直接嵌套调用:
- 多个条件可分别柯里化后组合:
isActive(users).filter(isVerified(users)) - 或用 reduce 实现多条件合并:
conditions.reduce((acc, fn) => fn(acc), data) - 也可以返回一个“配置对象”,让调用端更语义化:
filter.where('role').equals('admin')
注意边界情况和类型安全
实际项目中要注意几点:
- 字段不存在时,
item[key]是undefined,做比较前最好加空值判断或默认值处理 - 字符串比较建议统一转成字符串(
String(itemValue)),避免123和"123"不匹配 - 如果数据量大,别在柯里化函数里做深克隆或复杂计算,保持纯函数特性
- TypeScript 下可给柯里化函数标注泛型,明确
key必须是对象的合法属性名


















