map(&: ~ )の(&:)とはなんなのか
こんにちは。
今日は、AtCoderを解いていて、よく見かけたmap(&:~)とはなんなのか調べたので、備忘録くらいの感覚で書いていきたいと思います。
mapメソッドとは
まず初めにmapメソッドとは。
各要素に対してブロックを評価した結果を全て含む配列を返します。
すべて 3 倍にした配列を返す
p (1..3).map {|n| n * 3 } # => [3, 6, 9]
とのことで、この例題を見るとわかりやすいですよね。
mapのあとにあるブロックを1、2、3に適応していく。
このような使い方だと自分でも使えそうです。
しかし、AtCoderでよく見るのは、入力に対してmapメソッドを使う場面です。
よくある問題の入力値の獲得方法として、
入力 "12 3"
結果 a= 12 b = 3
のように複数の値の獲得をスペースを含めた一回で値を獲得します。
この時に必要になるのが、map(&: ~ )
なんですねぇ
(&: ~ )について
米 スペースを含めた入力についてはsplitメソッドを使いスペースごとに一つの値として区切り配列にしまうようになっています。
では、本題の(&: ~ )について。
先ほどもあった通り、mapメソッドはブロック適応し結果を返します。
でもmap(&: ~ )
って公式に書いてあった{|n|}。これないじゃん。(&: ~ )
これなにしてんねん。
なりますよねぇ。
肝心なのは、&
!
この&
はそのメソッドをブロックとして展開する役割があるとのこと!
つまり
map(& )
はmap{}
というふうに展開される!
そして、入力された値は数値として獲得したいので、map(& to_i)
として値を獲得できそうです。
しかし、現場のa.map(& to_i)
では、"to_i"
という文字列を適応してしまいます。
なので(&:to_i)
のようにシンボルとして渡すことでメソッドとして渡すことができる。ということでした!!
#式にて捕捉。
(1..3).map(& to_i)
# これでは、
# => 1."to_i", 2."to_i", 3."to_i" になってしまう。
(1..3).map(&:to_i)
#:をつけることで
# => 1.to_i, 2.to_i,3.to_i となりメソッドとなる。
# また、上記は下記と同じこととなる。
(1..3).map{|x| x.to_i}
クソお世話になった記事
では。