Ruby 关于 inject, 疑惑的地方.

torvaldsdb · 2018年02月03日 · 最后由 msg7086 回复于 2018年02月04日 · 1395 次阅读

在控制台遇到的问题,看着相似,结果却截然不同。 意图:累加,如果小于 2, 就 +1, 如果大于 3, 就 +2

(1..5).inject(0) do |sum, a|
  next sum + 1 if a <2
  next sum + 2 if a >3
  sum
end

输出结果:=> 5

(1..5).inject(0) do |sum, a|
  next sum + 1 if a <2
  sum + 2 if a >3
  sum
end

输出结果:=>1

(1..5).inject(0) do |sum, a|
  next sum + 2 if a >3
  next sum + 1 if a <2
  sum
end

输出结果:=>5

(1..5).inject(0) do |sum, a|
  next sum + 2 if a >3
  sum + 1 if a <2
  sum
end

输出结果:=>4

究竟问题出在哪里?

  • 结果为1 是因为a > 3返回的是 sum,而不是sum+2
  • 结果为4 是因为a < 2返回的是 sum,而不是sum+1

next 的参数会成为 inject block 的返回值

看一遍 inject 的文档就知道了 http://devdocs.io/#q=ruby+inject

或者可以看我这篇里的解释 https://ruby-china.org/topics/34620#inject/reduce

我想你并不是像楼上两位指出的你不懂 inject or reduce 是怎么工作的,你应该是知道 sum 是上一个 interation 最后一行的返回值 (或者是 next/break 后面的返回值)。

我觉得你没弄清楚的是 sum + 1 或 sum + 2 这命令是不会改变 sum 本身的,所以对于没有 next 前置的命令,比如 sum + 1 if a > 3 是不改变 sum 的,block 最后返回的 sum 是还没累加过的 sum, 不信你可以放个 pry 在 block 里的倒数第二行

改成 sum += 1, sum = sum + 1, 就会得到你想要的结果

第二段的 sum + 2 if a >3

第四段的 sum + 1 if a <2

都相当于空行。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号