2017-02-20 3 views
0

このコードに対する私の期待は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 

答えて

1

あなたはほとんどそこにあった。

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 
0

あなたは動作しません持っているどのような理由:

  1. memo += num if num.is_a?Integerの値のときはIntegerではありません。
  2. 各ブロックの値は、次の反復に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 } 
... 

が、それはおそらく、あまりにも多くの仮定を作っています。

0

あなたは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を返すようにしたい
0
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::IntegerKernel::Floatを参照してください。

関連する問題