このコードに対する私の期待は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
として入力されます。あなたが評価しようと終わるつもりですので、あなたのブロックは、2回目の繰り返しでnil
に評価されます。
nil += 2 if 2.is_a? Integer
とあなたのNoMethodErrorがあります。
おそらく明確にするため2つの段階でこれを行う方がいいでしょう:
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 }
...
が、それはおそらく、あまりにも多くの仮定を作っています。
あなたは2段階の操作ではなく、一人としてそれを考慮すれば、あなたは多くのより簡単にこれを行うことができます。
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
でる。
配列が1つまたは複数のフロートを含むことができ、あなたがfloatを返すようにしたい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
はKernel::IntegerとKernel::Floatを参照してください。