injectreduce 互为别名, 性能上没有差别.

#inject 方法在 Enumerable 模块中提供, 在所有可迭代的对象中可用.

典型使用场景

def calc(items)
  sum = 0
  items.each do |item|
    sum += item
  end
  sum
end

puts calc [3, 4, 7]
# 14

对于这样一个求和的计算, 临时变量 sum 是可以优化掉的:

def calc(items)
  items.inject(0) { |sum, item| sum + item }
end

puts calc [3, 4, 7]
# 14

参数解释

完整模式

items.inject(init_value) do |result, item|
  # some operation ...
  result_new_value = func(item)
end

items 是一个可迭代对象.

init_value 用来初始化 result.

从 items 的第一个元素开始, 依次赋值给 item.

block 的返回重新值赋值给 result.

迭代直到完成.

返回值为最终的 result.

缩略模式

items.inject do |result, item|
  # some operation ...
  result_new_value = func(item)
end

可以不设置 init_value, 它会自动把 items 的首元素当做初始化元素来使用, 然后从第二个元素开始迭代.

极简模式

items.inject(:+)

items 的第一个元素初始化结果, 从 items 的第二个元素开始与结果操作.

也可以设置结果的初始值:

# 注意: 小括号 和 逗号
items.inject(1000, :+)