lodash _.flow中使用map/reduce/filter不生效问题及正确用法咨询
问题根因
你写的组合逻辑完全没匹配lodash原生的调用规则,两处核心错误导致flow执行时根本没触发过滤逻辑:
- 普通版本lodash的
_.filter原生参数顺序是先传入待处理的集合,再传入过滤迭代器,和你以为的“先传规则、后传数据”的偏函数模式逻辑完全相反。你写的_.filter(val=>val<=100)属于直接调用filter方法,把自己写的过滤箭头函数当成第一个参数(待处理数据集)传进去了,既没拿到过滤结果,也没生成“等接收数据集再执行过滤”的可组合函数——这次调用直接执行完毕,返回的结果根本不是函数。 _.flow要求每一步必须传入可执行的函数,你传进去的两个“过滤步骤”实际是普通数组(非函数),正常执行会触发类型报错;就算不报错,这两个非函数值根本没法承接上一步传过来的数组数据,flow会直接把最初传入的scores透传出去,最终输出和原数组完全一致。
正确搭配方式
要把map、reduce、filter这类lodash方法和_.flow组合,常用的有三种可直接落地的写法:
方法1:自己封装接收数组的纯函数
直接把过滤逻辑封装成接收数组为入参的普通函数,完全不用适配lodash的特殊参数规则,可读性最好:
const _ = require('lodash'); const scores = [50, 6, 100, 0, 10, 75, 8, 60, 90, 80, 0, 30, 110]; // 自定义纯函数,接收数组作为第一个参数 const rmvOverScores = (arr) => _.filter(arr, val => val <= 100); const rmvZeroScores = (arr) => _.filter(arr, val => val > 0); // flow按顺序流转:先把scores传给rmvOverScores,输出结果再传给rmvZeroScores const aboveZeroLess100 = _.flow(rmvOverScores, rmvZeroScores)(scores); console.log(aboveZeroLess100); // 输出和你最初分步调用的结果完全一致
方法2:手动柯里化lodash方法做预绑定
如果想要贴合“先写规则、后传数据”的函数式写法,可以用lodash提供的柯里化能力,把原生filter转成支持分步传参的版本,生成真正可组合的函数:
const _ = require('lodash'); // 把原生_.filter转成2参数的柯里化版本,支持分步传参 const filter = _.curry(_.filter, 2); // 现在生成的两个变量都是可组合的函数 const rmvOverScores = filter(val => val <= 100); const rmvZeroScores = filter(val => val > 0); const aboveZeroLess100 = _.flow(rmvOverScores, rmvZeroScores)(scores);
方法3:直接使用lodash/fp版本
如果本来就是围绕函数管道、函数组合的场景使用lodash,直接引入lodash/fp包即可。这个版本的所有方法已经默认做了柯里化处理,参数顺序自动调整为“先传规则、后传数据”,和你最初的写法逻辑最贴近:
// 注意引入的是fp版本,不是默认的普通lodash const _ = require('lodash/fp'); const scores = [50, 6, 100, 0, 10, 75, 8, 60, 90, 80, 0, 30, 110]; // 此时_.filter只传一个规则参数,会返回一个等待接收数组的函数 const rmvOverScores = _.filter(val => val <= 100); const rmvZeroScores = _.filter(val => val > 0); const aboveZeroLess100 = _.flow(rmvOverScores, rmvZeroScores)(scores); // 输出结果符合预期
常见误区
- 不要误以为普通版lodash的方法都自动支持偏应用/柯里化。只有手动调用
_.curry处理,或者使用lodash/fp版本时,方法才会在少传参数时返回等待剩余参数的函数。 _.flow的执行顺序是从左到右,每一步的输出会作为下一步的输入,所有传入的步骤必须是真正的可调用函数,不能是其他类型的值。
内容的提问来源于stack exchange,提问作者Woden
相关产品推荐
相关产品推荐

