柯里化是将多参数函数转换为一系列单参数函数的过程,可预先固定字段名、操作符等筛选条件,提升过滤逻辑的灵活性与复用性,并支持路径访问、类型安全及自动推导操作符等增强特性。

柯里化是把多参数函数转换为一系列单参数函数的过程。在实现通用过滤器时,它能让你预先固定部分筛选条件(比如字段名、比较操作符),后续只需传入具体值,让过滤逻辑更灵活、可复用。
基础柯里化过滤器:字段 + 操作符预设
先写一个支持常见比较操作的柯里化函数,例如 filterBy(field, operator),返回一个等待值的函数:
const filterBy = (field, operator) => (value) => (item) => {
const itemValue = item[field];
switch (operator) {
case 'eq': return itemValue === value;
case 'gt': return itemValue > value;
case 'lt': return itemValue
<p>这样你就能预设字段和行为:</p>
const filterByNameStarts = filterBy('name', 'startsWith');const filterByAgeGt = filterBy('age', 'gt');
再配合 Array.prototype.filter 使用:
const users = [{name: 'Alice', age: 25}, {name: 'Bob', age: 30}];
users.filter(filterByNameStarts('Al')); // → [{name: 'Alice', age: 25}]
users.filter(filterByAgeGt(28)); // → [{name: 'Bob', age: 30}]
支持组合与链式过滤:用柯里化 + 函数组合
单一过滤器常需叠加。可借助柯里化构造可组合的过滤器工厂,并用 compose 或简单串联实现多条件:
const and = (...fns) => (item) => fns.every(fn => fn(item));
// 预设多个过滤器
const nameIncludes = filterBy('name', 'includes');
const ageGt = filterBy('age', 'gt');
const activeFilter = and(nameIncludes('a'), ageGt(20));
users.filter(activeFilter); // 同时满足两个条件
这种写法保持了每个过滤器的独立性和可测试性,也便于动态拼装。
增强实用性:支持路径访问与类型安全
真实数据中字段可能是嵌套的(如 user.profile.city),可用 Lodash 风格的 get 工具或简易路径解析:
const get = (path, obj) => path.split('.').reduce((o, k) => o?.[k], obj);
const filterByPath = (path, operator) => (value) => (item) =>
filterByOperator(operator)(get(path, item), value);
const filterByOperator = (op) => (a, b) => {
switch (op) {
case 'eq': return a === b;
case 'in': return Array.isArray(b) ? b.includes(a) : false;
// 其他操作...
}
};
现在可以这样用:
filterByPath('profile.city', 'eq')('Beijing')filterByPath('tags', 'in')(['admin', 'user'])
小技巧:自动推导操作符,减少冗余参数
如果传入的是数组,自动用 in;是字符串且含通配符(如 *abc),自动转为 endsWith;这样调用更自然:
const smartFilter = (field) => (value) => {
const op = Array.isArray(value) ? 'in' :
typeof value === 'string' && value.startsWith('*') ? 'endsWith' :
'eq';
return filterBy(field, op)(value.replace('*', ''));
};
使用示例:
data.filter(smartFilter('role')(['admin', 'editor']))-
data.filter(smartFilter('name')('*son'))→ 匹配以 son 结尾的名字
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











