2016-07-04 62 views
-2

請幫助我理解迭代在String實例和自定義類實例之間的區別。Ruby在遍歷自定義類實例時返回實例

a = ["pew", "pie"] 
a.inject do |memo, instance| 
    memo + instance 
end 

它工作正常。按預期返回「pewpie」。

class Boom 
    def slash 
    3 
    end 

    def ping 
    5 
    end 
end 

a = [Boom.new] 
a.inject do |memo, instance| 
    memo + instance.slash + instance.ping 
end 

這出於某種原因返回實例本身 - 繁榮:0x00000005018a38

+0

只有1元件'Boom.new'在陣列。因此它不會遍歷... –

回答

3

關鍵的一點是這個音符inject文檔中: 如果你不明確指定備忘錄的初始值,則第一集合的元素被用作備忘錄的初始值。

在你的情況,你應該這樣做

a.inject(0) { |memo, instance| memo + instance.slash + instance.ping } 
# 8 

否則你用型臂,備忘錄的對象的引用。

+0

你是對的。謝謝。 – fieryvova

2

當沒有累加器的初始值時,使用第一個元素。如果有隻有一個數組元素的 - 塊將不會運行:

[1].inject{ raise "Boom!" } 
# => 1 
[1].inject(0){ raise "Boom!" } 
# => RuntimeError: Boom! 

所以,你需要或者提供初始值的重新定義+運營商類。

+0

謝謝。你是對的。 – fieryvova

1

這裏有兩種解決方案:

a = [Boom.new, Boom.new, Boom.new] 
# => [#<Boom:0x007ffaf90a9c08>, #<Boom:0x007ffaf90a9be0>, #<Boom:0x007ffaf90a9bb8>] 

# 1) memo is a String 
a.inject('') {|memo, instance| memo + instance.slash.to_s + instance.ping.to_s} 
# => "353535" 

# 2) memo is an Array 
a.inject([]) {|memo, instance| memo << instance.slash.to_s + instance.ping.to_s} 
# => ["35", "35", "35"] 

見:http://ruby-doc.org/core-2.3.1/Enumerable.html#method-i-inject

+1

謝謝!我的錯。我應該更加註意地閱讀文檔。 – fieryvova