0

1 つのチュートリアルには、次のコード ブロックがあります。

h1 = ["a" => 111, "b" => 222]
h2 = ["b" => 333, "c" => 444]
h1.merge(h2) {|key, old, new| new}
# => ["a" => 111, "b" => 333, "c" => 444]
h1.merge(h2) {|key, old, new| old}
# => ["a" => 111, "b" => 222, "c" => 444]

マージと競合しています。2 つの配列にまたがる 2 つの重複キー。はの の値をnewキャプチャしており、それを出力するとマージで優先されます。同様に、はの の値をキャプチャし、強制的に優先させます。h2"b"oldh1"b"

の値しか取得していないように見えるのはなぜ"b"ですか? 変数が配列全体を取得するべきではありませんか? ブロック変数は.merge、たとえば とは対照的に、 と一緒に使用すると、状況に依存し、機能を変更し.timesますか? それとも、単純な数値の代わりに配列を扱っているときに機能が変わるのでしょうか? それとも、マージの競合を見て、「競合のポイントを把握しなければならない」ようになっているのでしょうか? 何が入っているか見てみようかなと思ったのですがkey

h1.merge(h2) {|key, old, new| key}
# => ["a" => 111, "b" => "b", "c" => 444]

しかし、それは実際には私をもっと混乱させました。1 つの変数がキーをキャプチャしているのに、他の変数が 2 つの異なる値をキャプチャしているのはなぜですか?

4

3 に答える 3

2

マージしています: ではh1.merge(h2)、「h1」は「古い」ハッシュであり、「h2」は「新しい」ハッシュです。このブロックは、両方のハッシュに値を持つキーに対してのみ呼び出されます。ブロックは 3 つの引数を取得します: 各キーと各ハッシュからの対応する値です。ブロック内のロジックは、そのキーの出力ハッシュに入れるものを選択します。1 つのハッシュにのみ含まれるキーは、ブロックを介して処理されることなく直接出力されます。

実行すると、何が起こっているのかをよりよく理解できるかもしれません

 h1.merge(h2){|key,left,right| print "k=#{key} l=#{left} r=#{right} "}

Ruby-Doc.orgの説明から:

other_hash の内容と hsh の内容を含む新しいハッシュを返します。ブロックが指定されていない場合、重複キーを持つエントリの値は other_hash の値になります。それ以外の場合、各重複キーの値は、キー、hsh の値、other_hash の値を使用してブロックを呼び出すことによって決定されます。

したがって、特定の質問の1つに答えるために、ブロックは、キーごとに呼び出される.eachや.delete_ifなどのメソッドとは異なり、競合するキーに対してのみ条件付きで呼び出されます。

于 2012-10-04T13:29:51.880 に答える
1

ruby でブロックとブロック変数がどのように機能するかを研究することをお勧めします。

たとえば、このリソースが役立つ場合があります。

于 2012-10-04T13:40:21.923 に答える
0

mergeのドキュメントから。3 つのパラメーターkey, old, newは、次のように使用されます。

  • ハッシュの 1 つだけに存在する場合key、そのハッシュの値を使用してマージが構築されます
  • 両方のハッシュに存在する場合key、proc (ブロック) からの戻り値{|key, old, new| key }が返されます。この場合はkey、ハッシュに挿入されるキーです。

{|key, old, new| old - new }2 つのハッシュ間でキーの競合が発生したときに計算を呼び出すなど、他のことを行うこともできます。マージのドキュメントの例を次に示します。

h1 = { "a" => 100, "b" => 200 }
h2 = { "b" => 254, "c" => 300 }
h1.merge(h2)   #=> {"a"=>100, "b"=>254, "c"=>300}
h1.merge(h2){|key, oldval, newval| newval - oldval}
               #=> {"a"=>100, "b"=>54,  "c"=>300}
于 2012-10-04T13:34:03.847 に答える