如何使用.reduce()调用函数数组中的函数并作用于指定字符串?
用Array.reduce实现Redux的compose功能,让函数数组作用于字符串
当然可以用reduce(或reduceRight)实现Redux的compose逻辑,让函数数组里的所有函数依次作用于目标字符串。Redux的compose本质是从右往左依次执行函数,把前一个函数的输出作为后一个函数的输入,也就是compose(f1, f2, f3)(x) = f1(f2(f3(x)))。
先给示例函数补全具体逻辑,方便观察执行结果:
function fun1(str) { return `[fun1处理后] ${str}`; } function fun2(str) { return `[fun2处理后] ${str}`; } function fun3(str) { return `[fun3处理后] ${str}`; } const funcArray = [fun1, fun2, fun3]; const someString = "Trying to create compose from redux using reduce";
1. 实现和Redux compose一致的从右往左执行
Redux的compose是从数组最后一个函数开始执行,用reduceRight最直接:
// 先组合出compose后的函数 const composedFunc = funcArray.reduceRight((prev, curr) => { return (val) => curr(prev(val)); }, (val) => val); // 初始值是返回输入本身的恒等函数 // 让组合函数作用于字符串 const result = composedFunc(someString); console.log(result); // 输出:[fun1处理后] [fun2处理后] [fun3处理后] Trying to create compose from redux using reduce
这里的逻辑是从右往左遍历函数数组,每次把当前函数和之前组合好的函数嵌套,最终得到一个按compose规则执行的函数。
2. 直接用reduce处理字符串(无需先组合函数)
如果不需要预先得到组合后的函数,直接让所有函数依次处理字符串也可以:
// 模拟Redux compose的从右往左处理 const rightToLeftResult = funcArray.reduceRight((acc, func) => func(acc), someString); console.log(rightToLeftResult); // 输出和上面一致 // 从左往右依次处理(顺序和compose相反) const leftToRightResult = funcArray.reduce((acc, func) => func(acc), someString); console.log(leftToRightResult); // 输出:[fun3处理后] [fun2处理后] [fun1处理后] Trying to create compose from redux using reduce
这种方式更简洁,直接把目标字符串作为reduce的初始值,用每个函数迭代处理累加值即可。
3. 用reduce实现从右往左的compose(不用reduceRight)
如果不想用reduceRight,也可以反转数组后用普通reduce:
const composedFuncReverse = [...funcArray].reverse().reduce((prev, curr) => { return (val) => prev(curr(val)); }, (val) => val); const resultReverse = composedFuncReverse(someString); console.log(resultReverse); // 输出和Redux compose一致
总结:不管哪种方式,都能让函数数组里的所有函数作用于目标字符串。如果要严格匹配Redux compose的从右往左执行逻辑,优先用reduceRight或者反转数组后再用reduce。
内容的提问来源于stack exchange,提问作者Fclass
相关产品推荐
相关产品推荐

