熟悉的陌生方法,经常在代码里遇见,混了个脸熟,看代码基本都能理解——但是到自己想用的时候,却又不甚了解具体细节,只能作罢。

Enumerable#reduce(同inject)

文档:

Combines all elements of enum by applying a binary operation, specified by a block or a symbol that names a method or operator.

If you specify a block, then for each element in enum the block is passed an accumulator value (memo) and the element. If you specify a symbol instead, then each element in the collection will be passed to the named method of memo. In either case, the result becomes the new value for memo. At the end of the iteration, the final value of memo is the return value for the method.

If you do not explicitly specify an initial value for memo, then the first element of collection is used as the initial value of memo.

废话不多说。
(5..10).reduce(:+) # => 45
将Enum中每个值都用应用 ‘+’ 符号,初始值未指定,故设置为第一个参数5,之后进行 ‘+’ 的累积。

(5..10).reduce(10, :+) => 55
同上,但是初始值设置成了10。

[1,2,3].reduce(10) do |memo, num|
  memo = memo + num
end
memo为初始值,且被赋值为10, block中的语句每一次执行的结果都赋给了memo。注意,此处是把执行语句的结果赋给了memo,并非因为 = 操作。

[1,2,3].reduce(10) do |memo, num|
  memo = memo + num
  puts memo
  500
end
得到:
11
502
503

memo并不是由=来决定值,而是由最后一个语句500决定值。不多说了。

longest = %w{ cat sheep bear }.reduce do |memo, word|
  memo.length > word.length ? memo : word
end
memo为初始值,block中的语句每一次执行的结果都赋给了memo。

Array#map

文档:

Invokes the given block once for each element of self. If no block is given, an Enumerator is returned instead.

[1,2,3,4].map { x x + “!”} => [“a!”, “b!”, “c!”, “d!”]