一次搞懂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