Ruby 关于 inject, 疑惑的地方.

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

在控制台遇到的问题, 看着相似, 结果却截然不同. 意图: 累加, 如果小于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

究竟问题出在哪里?

共收到 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

都相当于空行。

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