2

2つの配列を1つのハッシュに変換する方法を探していました。私はこのようなものを見つけました:

a1 = [1,2,3]
a2 = [?A, ?B, ?C]
Hash[*a1.zip(a2).flatten]

Hash[a1.zip a2]まったく同じことをするので、この構文は少し奇妙だと思いました。しかしそれ以上に、私は*オペレーターの必要性を理解していません。

オブジェクトを配列などに変換することは知っています(ただし、同じ方法ではないようです[])。

私が実行するとき:

a = a1.zip(a2).flatten
 => [1, "A", 2, "B", 3, "C"]
a = *a1.zip(a).flatten
 => [1, "A", 2, "B", 3, "C"]

実際には何も起こりません。私が*オペレーターについて知っていることでは、これは正常な動作のようです。

それで、なぜ

Hash[*a1.zip(a2).flatten]
 => {1=>"A", 2=>"B", 3=>"C"}
Hash[a1.zip(a).flatten]
 => {}

パラメータが同じように見える場合、異なる値を返しますか?

私は*オペレーターについて何かが欠けているに違いないと思います。

ありがとう。

4

3 に答える 3

4

*演算子がそのような配列で使用される場合、それはスプラット演算子と呼ばれます。

配列の周りの最初のレベルの角かっこを削除する演算子と考えてください。配列を引数リストに変換できるため、これは非常に便利です。

def stuff(x, y, z)
end

a = [1, 2, 3]
stuff(*a) # x,y,z gets assigned 1,2,3

同じことが。でも機能しHash[]ます。onの[]演算子Hashは、引数として受け入れます。

  1. キーと値のペアの引数リスト:
    Hash["a", 1, "b", 2] #=> { "a" => 1, "b" => 2 }
  2. キー値を表す1つまたは複数の配列ペア:
    Hash[ [["a", 1], ["b", 2]] ] #=> { "a" => 1, "b" => 2 }

Hash[]プレーンフラット配列を引数として受け入れません:

Hash[ ["a", 1, "b", 2] ] #=> {}

したがって、これを念頭に置いて、さらにスプラットオペレーターが何をしているのかを理解することで、何が起こっているのかを確認できます。

paired_array = a1.zip(a2)
=> [[1, "A"], [2, "B"], [3, "C"]]

plain_array = a1.zip(a2).flatten
=> [1, "A", 2, "B", 3, "C"]

# Per rule 2 above we know this works
Hash[paired_array]
=> {1=>"A", 2=>"B", 3=>"C"} 

# This won't work
Hash[plain_array]
=> {}

# But if we turn the plain_array into an argument list, 
# then we know per rule 1 above that this will work
Hash[*plain_array]
=> {1=>"A", 2=>"B", 3=>"C"} 

さて、あなたはあなたがそうするときにちょっと何が起こっているのか疑問に思うかもしれません:

a = *plain_array
=> [1, "A", 2, "B", 3, "C"]

スプラット演算子がブラケットを効果的に削除することがわかっているので、次のようになります。

a = 1, "A", 2, "B", 3, "C"

...おかしなことに、これは有効なRubyコードであり、配列を再度作成するだけです。

splat演算子のrubyspecテストケースで、splat演算子に関するもっと楽しいものを読むことができます。

于 2012-06-27T09:39:45.377 に答える
2

あなたの例には間違いがあると思います。次のようになります。

Hash[a1.zip(a2).flatten] #=> {}
Hash[*a1.zip(a2).flatten] #=> {1=>"A", 2=>"B", 3=>"C"}

割り当てモードのsplat演算子は、配列を複数の引数に変換します。

duck, cow, pig = *["quack","mooh","oing"] #=> ["quack","mooh","oing"]

実はそれは

duck, cow, pig = ["quack","mooh","oing"] #=> ["quack","mooh","oing"]

しかし、ドキュメントから、 Hash [...]が複数の引数を受け取ることがわかります。したがって、splat演算子は、これらの複数の引数のそれぞれを割り当てるのに役立ちます。

于 2012-06-27T09:33:26.873 に答える
1

それはそれほど神秘的ではありません:

a1 = [1,2,3]
a2 = [?A, ?B, ?C]

p Hash[*a1.zip(a2).flatten] #{1=>"A", 2=>"B", 3=>"C"}

*、配列を(引数の)単なるリストに変換します。

しかし、なぜこの構文が使用されなかったのですか?

p Hash[a1.zip(a2)]# {1=>"A", 2=>"B", 3=>"C"}

さて、Ruby1.9.2以降の新機能です。あなたの例はおそらく古いです。

于 2012-06-27T10:04:02.697 に答える