2016-04-09 20 views
0

#inject içinde while döngüsünü kullanmaya çalışıyorum. Ancak, son not bir noktada sıfır olur ve nedenini anlamıyorum.#inject'deki not nasıl çalışır?

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 

Nasıl akümülatör nil haline gelir: İşte benim örnek (Sadece beklenen sonucu göstermek için örnek üzerinde #each kullanın)?

cevap

1

Sen while loop dan başlangıçta nil alıyoruz:

sonuç döngüsünün break değeri, bir değer sağlamak için kullanılmadığı sürece nil'dur.

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

ilk olarak kullanmak için boş bir dizi sağlamak isteyeceksiniz, bir dizi doldurmak .inject sağlamak için: sonuçlanabilir

bir zincirindeki diğer tabloların sonucu olur memo: O

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

, dizi bloğunun sonucudur emin olun:

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

Teşekkürler, @jonathan! 'While''in dönüş değeri hakkında açıklama 'artı', 'not' i geri getirdiğini bilmediğimi bilmeme yardımcı oldu. Teşekkürler! – user3097405

1

İki şey:

  • Bu durumda, bir [] isteyeceksiniz, bir değerle memo başlatmak gerekir.
  • inject'un her yinelemesinde memo'u döndürmeniz gerekir.

Yani, bu gibi olmak için yönteminizi değiştirerek [5, 5, 1] sizin istenen sonucu almak gerekir:

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

Thanks @paul! [[] 'Notunun eksik olması, soruyu yazdığımda bir hataydı, fakat notu geri göndermiyordum ve sorun buydu. Yardım ettiğin için teşekkür ederim! – user3097405