#inject中的备忘录如何工作?

时间:2016-04-09 23:42:41

标签: ruby

我正在尝试在while内使用#inject循环。但是,最后一份备忘录在某些时候变为零,我不明白为什么。这是我的示例(我在示例中仅使用#each来显示预期结果):

class TestClass
  BASE_ARRAY = [5, 1]

  def test_method(value)
    result = []

    BASE_ARRAY.each do |item|
      while item <= value
        result << item
        value -= item
      end
    end

    result
  end

  def test_method_alternate(value)
    BASE_ARRAY.inject do |memo, item|
      while item <= value
        p memo
        # memo << item (if left, returns NoMethodError for nil Class)
        value -= item
      end
    end
  end
end

solution_one = TestClass.new.test_method(11)
p solution_one # => [5, 5, 1]

solution_two = TestClass.new.test_method_alternate(11)
p solution_two 
# => [] 
     [] 
     nil  

累加器如何成为nil

2 个答案:

答案 0 :(得分:1)

两件事:

  • 您需要使用值初始化memo,在这种情况下,您需要[]
  • 您需要在memo的每次迭代中返回inject

所以,你应该通过改变你的方法得到你想要的[5, 5, 1]结果:

def test_method_alternate(value)
  BASE_ARRAY.inject([]) do |memo, item|
    while item <= value
      memo << item
      value -= item
    end
    memo
  end
end

答案 1 :(得分:1)

您最初从while loop获得nil

  

while循环的结果为nil,除非break用于提供值。

该结果成为链中其他陈述的结果:

while
-> do |memo, item|
  -> BASE_ARRAY.inject
    -> test_method_alternate(11)
      -> solution_two

要让.inject填满数组,您需要提供一个空数组作为第一个memo

BASE_ARRAY.inject([]) do |memo, item|
# ...            ^^^^

然后,确保数组是块的结果:

... do |memo, item|
  while item <= value
    memo << item
    value -= item
  end
  memo # <---
end