【问题标题】:Why does these two injects give the same output in ruby?为什么这两个注入在 ruby​​ 中给出相同的输出?
【发布时间】:2014-08-13 19:05:08
【问题描述】:

为什么输出一样?

第一次注入:

puts (3...10).inject(0) { |sum, x| (x % 3 == 0 || x % 5 == 0) ? sum + x : sum }
# => 23

第二次注入:

puts (3...10).inject { |sum, x| (x % 3 == 0 || x % 5 == 0) ? sum + x : sum }
# => 23
# Why not 26?

我想如果没有参数传递给它,inject 使用集合的第一个元素作为初始值。

所以第二次注入应该返回与这次相同的值:

puts (3...10).inject(3) { |sum, x| (x % 3 == 0 || x % 5 == 0) ? sum + x : sum }
# => 26

【问题讨论】:

    标签: ruby inject


    【解决方案1】:

    为什么这两个注入在 ruby​​ 中给出相同的输出?

    ...因为他们应该这样做。它们的区别仅在于添加了 0

    我想如果没有参数传递给它,inject 使用集合的第一个元素作为初始值。

    确实如此。但它不会复制它。

    您的第一个示例收到这些数字:

    0, 3, 4, 5, 6, 7, 8, 9
    

    您的第二个示例收到这些数字:

    3, 4, 5, 6, ...
    

    在开头添加0 不会影响结果,它们都是 23,而不是您声称的 26。

    您的第三个示例返回 26,因为它收到了这些数字:

    3, 3, 4, 5, 6, ...
    

    【讨论】:

    • 第二个inject 中的sumx 不是都= 3 吗?所以sum 在第二次迭代中将是 6。而sum = 0 和x = 3 在第一个inject。所以sum 在第二次迭代中将是 3。
    • 我只是尝试了一些东西并想通了。 inject 获取集合的第一个元素并将其设置为 sum 作为第一次迭代的结果。我一直认为它将集合的第一个元素作为初始值,并且仍然执行第一次迭代。
    • @phre [1,2,3].inject { |sum,x| } 有 1 个 sum 和 2 个 x
    【解决方案2】:
    #inject() with an argument:
    
    result = (3...10).inject(0) do |sum, x| 
      puts "#{sum} <-- #{x}: sum = #{sum+x}"
      sum + x
    end 
    
    --output:--
    0 <-- 3: sum = 3
    3 <-- 4: sum = 7
    7 <-- 5: sum = 12
    12 <-- 6: sum = 18
    18 <-- 7: sum = 25
    25 <-- 8: sum = 33
    33 <-- 9: sum = 42
    

    ...

    #inject without an argument:
    
    result = (3...10).inject() do |sum, x| 
      puts "#{sum} <-- #{x}: sum = #{sum+x}"
      sum + x
    end 
    
    --output:--
    3 <-- 4: sum = 7
    7 <-- 5: sum = 12
    12 <-- 6: sum = 18
    18 <-- 7: sum = 25
    25 <-- 8: sum = 33
    33 <-- 9: sum = 42
    

    我一直认为它将集合的第一个元素作为 初始值并且仍然执行第一次迭代

    第一次迭代使用 arr[0] 作为总和,使用 arr[1] 作为第一个 x。当你不为 inject() 提供参数时,它相当于这样做:

    data = (3...10).to_a
    initial_sum = data.shift
    
    data.inject(initial_sum) do |sum, x|
      puts "#{sum} <-- #{x}: sum = #{sum+x}"
      sum + x
    end
    
    --output:--
    3 <-- 4: sum = 7
    7 <-- 5: sum = 12
    12 <-- 6: sum = 18
    18 <-- 7: sum = 25
    25 <-- 8: sum = 33
    33 <-- 9: sum = 42
    

    【讨论】: