一次搞懂Reduce,Inject方法

reduce与inject二者是等价的,reduce是inject的一个别名,从可读性上来看reduce更易阅读。 不过这也是相对的,要看你是从什么语言切过来的。先来看看关于reduce\inject的定义:

reduce(initial, sym)  obj
reduce(sym)  obj
reduce(initial) { |memo, obj| block }  obj
reduce { |memo, obj| block }  obj

再看些示例代码:

(1..8).reduce(:+)
=> 36

(1..8).reduce { |sum, num| sum += num }
=> 36

(1..8).reduce(0) { |sum, num| sum += num }
=> 36

第一行代码,会对(1..8)内的元素执行累加,没有给定initial值时,会默认选择调用集合中的第一个元素作为memo值,这里会选择1。reduce只返回最后一个memo结果值.后面两行代码通过代码块的形式进行调用,前者没有给初始值,后者给了initial为0的调用。

估计,你还是没有看的怎么明白,不要紧,来看看下面的图示,应该就没啥疑惑了。

reduce内部机制演示

下面图示以上面给出的第二行代码为例,通过折叠分别表示(1..8)这几个元素,折叠过程表示加和,每次加和的结果写到折叠的背面。以此类推直到不能折叠,也即遍历完集合中的元素。

(1..8).reduce { |sum, num| sum += num }

Loop Num Sum 1 1 1

Loop Num Sum 2 2 3

Loop Num Sum 3 3 6

Loop Num Sum 4 4 10

Loop Num Sum 5 5 15

Loop Num Sum 6 6 21

Loop Num Sum 7 7 28

Loop Num Sum 7 8 36

1
@foobar
加入
更多来自 foobar