2016-07-16 10 views
0

は、私は今、その現在の作品やっているものですが、私は少し糖衣構文に欠けていると感じ...ここinjectメソッドのブロックに渡される配列要素のブロックパラメータを個別に宣言できますか?ここ

f = RGeo::Geos.factory 
coords = [ [1,1], [2,2], [1,3] ] 
points = coords.inject([]) {|points, coord| points << f.point(coord[0], coord[1]); points } 
#=> [#<RGeo::Geos::CAPIPointImpl:0x3fff0950a508 "POINT (1.0 1.0)">, #<RGeo::Geos::CAPIPointImpl:0x3fff0950a47c "POINT (2.0 2.0)">, #<RGeo::Geos::CAPIPointImpl:0x3fff0950a454 "POINT (1.0 3.0)">] 

は私がやりたいものです。

points = coords.inject([]) {|points, x, y| points << f.point(x,y); points } 
#=> [nil, nil, nil] 

今は3つのnil値の配列を返しています。各メソッドで可能なように、注入ブロックに渡される要素の配列値を別々に宣言することは可能ですか?

サイドノート: 最初のインジェクションブロックパラメータ(「結果」変数)には同じ変数名を使用し、等号の左側には変数を使用するのが安全ですか?私は、これがちょうど再帰の典型的なケースになるので、はいと考えています。あなたが他に感じているか分かっていればコメントしてください。これは、トリックを行います

+0

'inject'、それが見える理由:

はまた、それらの外側の括弧は、厳密には、上記の例では必要ありませんが、一つだけの引数が配列から取られているとき、彼らは行動を変えることに注意してください'map'のようにしますか? –

+0

あなたが正しいと思います。私はそれを確かに考えた。 –

答えて

1

points = coords.inject([]) {|points, (x, y)| points << f.point(x,y); points } 

これは、任意のブロックに一般的に動作します。ブロックパラメータの1つがn個の要素の配列である場合、n個の括弧でくくられたパラメータ名を使用してこれらの要素を取得できます。あなたは括弧内のnパラメータ名以上を使用する場合は、エキストラはnilになります:あなたが少なすぎる、パラメータ名を使用する場合は

[[1,2,3],[4,5]].map {|(a,b,c)| "#{a}+#{b}+#{c.inspect}" } #=> ["1+2+3", "4+5+nil"] 

、残りは破棄されます。

[[1,2,3],[4,5]].map {|(a,b)| "#{a}+#{b}" } #=> ["1+2", "4+5"] 

あなたが使用することができます

[[1,2,3],[4,5]].map {|(a,*b)| "#{a}+#{b}" } #=> ["1+[2, 3]", "4+[5]"] 

あなたも巣を行うことができます普通の引数と同じように、代わりに、残りの部分をキャプチャするスプラットオペレータ

[[1,2,[3,4]],[5,6,[7,8]]].map {|(a,b,(c,d))| a+b+c+d } #=> [10, 26] 

これをネストするとかなり混乱することがありますので、控えめに使用してください。

# Makes no difference 
[[1,2,3],[4,5,6]].map {| a,b,c | "#{a}+#{b}+#{c}" } #=> ["1+2+3", "4+5+6"] 
[[1,2,3],[4,5,6]].map {|(a,b,c)| "#{a}+#{b}+#{c}" } #=> ["1+2+3", "4+5+6"] 

# Makes a big difference 
[[1,2,3],[4,5,6]].map {| a | a } #=> [[1, 2, 3], [4, 5, 6]] 
[[1,2,3],[4,5,6]].map {|(a)| a } #=> [1, 4] 
+0

うわー!私は、Rubyの構文能力について、それを使って4年間働いた後でも、引き続きどのように学習するのが大好きです –

関連する問題