0

このコードは配列を取り、一意の値のみを返します。

このコードが機能するために 2 番目の「キープ」が必要なのはなぜですか?? それがないと、次のエラーが発生します。

NoMethodError: 未定義のメソッド `include?' nil:NilClass の場合

class Array
  def my_uniq_inject
    self.inject([]) do |keep, num|
      keep << num unless keep.include?(num)
      keep  # why is this required?
    end
  end
end
4

6 に答える 6

5

arr << x通常は を返すので混乱するかもしれませんのでarr、大丈夫だと思います。

unlessここで物事を台無しにすることができるのはその部分です。配列の最後の要素が一意でない場合 (つまり、配列の前に既に出現している場合)、unless句によって式は に評価されnilます。

自分で見て:

arr = []
arr << 1              # [1]
arr << 2 unless false # [1, 2]
arr << 3 unless true  # nil
于 2013-06-19T14:18:18.457 に答える
2

inject/reduceはブロックの戻り値を受け取り、メモ/アキュムレータをそれに置き換えるためです。

each_with_objectメモを置き換えないものを使用できます

self.each_with_object([]) do |num, keep|
  keep << num unless keep.include?(num)
end
于 2013-06-19T14:14:48.293 に答える
1

2 つ目は、最初のパスの後にherekeepを再初期化するためのものです。最後の行の 2 番目の段落でドキュメントが言っているのを参照してください。繰り返しの最後に、 memo の最終値はメソッドの戻り値です。keepdo |keep,num|enum#inject

于 2013-06-19T14:14:45.950 に答える
1

keepブロックの結果は の次の反復のアキュムレータとして使用されるため、ブロックの最後に必要ですinject

それがなければkeep、ブロックの最初の行が返されることもありますが、返されることもありますkeepnil具体的には条件が満たされない場合)。

于 2013-06-19T14:14:49.717 に答える