reduce函数式编程初探

2,347 阅读2分钟
原文链接: zhuanlan.zhihu.com

一、 Reduce的用法

reduce是一种数组运算,通常用于将数组的所有成员"累积"为一个值:

reduce对数组arr的每个成员执行sum函数。sum的参数a是累积变量,参数b是当前的数组成员。每次执行时,b会加到a,最后输出a

累积变量必须有一个初始值,上例是reduce函数的第二个参数0。如果省略该参数,那么初始值默认是数组的第一个成员。

相应api如下:

二、 reduce的本质

  • 遍历
  • 变形
  • 累计

map是reduce的特例:累计变量的初始值也可以是一个数组

reduce包含了三种运算,因此非常有用。但也带来了一个问题:代码的复用性不高。在reduce里面,变形和累积是耦合的,不太容易拆分。

三、 reduce与redux中的compose函数

那么学习了reduce后,试着写个函数 能将多个函数进行组合成一个函数,也就是一元链式函数。例如:

使用reduce写一个函数,使这两个函数执行结果一样

代码实现如下:

function chained(funcs) {
 return function(params){ 
return funcs.reduce(function(params, fn){ return fn(params) }, params);
 }
 }

验证如下:

研究一下redux中compose函数的实现:

这里需要注意的是:reduce是从左到右处理(从第一个成员到最后一个成员),reduceRight则是从右到左(从最后一个成员到第一个成员),其他完全一样。

function chained(...funcs) { 
if (funcs.length === 0) {
     return arg => arg
 } 
if (funcs.length === 1) {
 return funcs[0] 
}
  return funcs.reduce((a, b) => (...args) => b(a(...args))) 
}

另附loadsh compose函数实现源代码,了解一下。

var flow = function(funcs) {
    var length = funcs.length
    var index = length
    while (index--) {
        if (typeof funcs[index] !== 'function') {
            throw new TypeError('Expected a function');
        }
    }
    return function(...args) {
        var index = 0
        var result = length ? funcs[index].apply(this, args) : args[0]
        while (++index < length) {
            result = funcs[index].call(this, result)
        }
        return result
    }
}
var flowRight = function(funcs) {
    return flow(funcs.reverse())
}