我對此代碼的期望是數字3.爲什麼這不起作用?在混合陣列中添加數字
mixed_array=[1,'cat',2]
mixed_array.inject(0) do |memo,num|
memo += num if num.is_a?Integer
end
NoMethodError: undefined method `+' for nil:NilClass
我對此代碼的期望是數字3.爲什麼這不起作用?在混合陣列中添加數字
mixed_array=[1,'cat',2]
mixed_array.inject(0) do |memo,num|
memo += num if num.is_a?Integer
end
NoMethodError: undefined method `+' for nil:NilClass
你幾乎有:
mixed_array.inject(0) do |memo, num|
next memo unless num.is_a?(Integer)
memo + num
end
#=> 3
使你的代碼工作:
mixed_array.inject(0) do |memo, num|
memo += num if num.is_a?(Integer)
memo # return memo on each iteration, because it becomes nil with non-integer element
end
#=> 3
你有什麼不工作,因爲:
memo += num if num.is_a?Integer
值當時是不是Integer
。memo
送入下一次迭代。你的塊計算爲nil
在第二次迭代所以你最終將會嘗試評估:
nil += 2 if 2.is_a? Integer
,並有你NoMethodError。
你可能更好做這兩個步驟清晰:
mixed_array.select { |e| e.is_a? Integer }.inject(:+)
,或者甚至較爲寬鬆的版本:
mixed_array.select { |e| e.is_a? Numeric }.inject(:+)
或使用Ruby的新版本:
mixed_array.select { |e| e.is_a? Numeric }.sum
如果你沒有教條主義反對三元論,那麼你也可以這樣說:
mixed_array.inject(0) { |memo, num| memo + (num.is_a?(Integer) ? num : 0) }
mixed_array.sum { |e| e.is_a?(Integer) ? e : 0 }
如果您知道的mixed_array
非數字元素是字符串看起來不像數字或以數字開頭(即沒有像'0'
,'11 pancakes'
,...),那麼你可以說:
mixed_array.map(&:to_i).inject(:+)
mixed_array.inject(0) { |memo, num| memo + num.to_i }
...
但是這可能使太多的假設。
你可以,如果你認爲它是一個兩個階段的操作,而不是一個很多更容易做到這一點:
mixed_array=[1,'cat',2]
mixed_array.grep(Integer).inject(0, :+)
# => 3
過濾掉來自陣列的所有非整數元素,共同增加了休息。
請記住,inject
將上次迭代的返回值作爲下一個的種子。您的if
條款必須返回一個備用值。你結束了這個,如果你解決它:
memo += num.is_a?(Integer) ? num : 0
你也可以去同一個足夠好的解決方案,如:
memo += num.to_i
取決於你試圖屏幕什麼樣的數據出。
mixed_array = [1, 'cat', 2, [3, 4], :a, { b: 5, c: 6 }, 7]
mixed_array.reduce(0) { |tot, obj| tot += Integer(obj) rescue 0 }
#=> 10
當陣列可以包括一個或多個浮標,並要返回浮點:
mixed_array = [1, 'cat', 2, [3, 4], :a, { b: 5, c: 6 }, 7, 8.123]
mixed_array.reduce(0) { |tot, obj| tot += Float(obj) rescue 0 }
#=> 18.122999999999998