map/collect

るびまのこの辺とゆーかDanさんのこのエントリで話題に上ってた,map/collect.動作自体に違いは無いらしいのですが,何故か

互いに血で血を洗う派閥抗争に明け暮れている

らしいです.そして,Ruby作者のまつもとゆきひろさんはcollect派と.どーも,ハッカーと言うか,プログラミング歴が長く,しかも色んな言語に触ってるような人が,気にするような事でしょ.んじゃボクにはまだ関係無さそうだなぁ.とりあえずタイプ数が少ないmapで良いや.

collect {|item| ... }
map {|item| ... }
各要素に対してブロックを評価した結果を全て含む配列を返します。

ブロックを省略した場合、

obj.collect {|item| item}
を行います。これは Enumerable#to_a と同じで す。

ほう.
実際に試してみました.

> a = [1,2,3,4,5]
=> [1, 2, 3, 4, 5]
> a.map{|e| e = 2}
=> [2, 2, 2, 2, 2]
> a.map{|e| e == 2}
=> [false, true, false, false, false]
> str = "hoge"
=> "hoge"

以前も使ったけれど,配列の場合,map!とすると破壊的になるんですよね.でもでも,正直,評価してtrueかfalseだけ返されても,いまいち使い道が分かんないと言うか.


Stringでも使えるんだけど,

> str = "hoge"
=> "hoge"
> str.map
=> ["hoge"]
> str.map{|e| e}
=> ["hoge"]
> str.map{|e| e == "o"}
=> [false]
> str.map{|e| e == "hoge"}
=> [true]

ふーん,ってかんじ.良くわかんない.

> b = [1,2,3,2,2]
=> [1, 2, 3, 2, 2]
> b.map{|e| e == 2}
=> [false, true, false, true, true]
> b.select{|e| e == 2}  
=> [2, 2, 2]
> b.select{|e| e == 2}.size
=> 3

こーゆーことができるし,折角Enumerableな感じにするなら,selectの方が使いやすいかもとか思ったり.

> c = b.map{|e| e == 2}
=> [false, true, false, true, true]
> c.each_index{|i|
irb(main):044:1* puts i if c[i]
irb(main):045:1> }
1
3
4
=> [false, true, false, true, true]

こーゆー使い方も出来るのか.