Container.each, collect, mapについて

戻り値

  • eachは最後の戻り値がそのまま返る。continue時はその前の、break時はbreakの引数が戻り値になる
  • collectは常にArrayを返す。continueした値やbreak以降の値は戻り値に含まれない
  • mapはselfと同じ型のコンテナを返す。continueした値やbreak以降の値はそのままになる

引数

  • 最後が実行されるメソッド
  • 最後から二番目がある場合、数値なら一度に扱う要素の数を示す数値、数値でなければ一緒に走査するコンテナ
  • それ以外の引数はすべて一緒に走査するコンテナ

コピーと破壊

  • each_ref, collect_refは要素をそのままメソッドに渡す
  • each_copy, collect_copyは要素をコピーしてメソッドに渡す
  • mapは別物なのでmap_ref, map_copyは無く、そのまま要素を渡す
  • eachはeach_ref
  • collectはcollect_copy
  • collect_without_copyはcollect_ref
  • collect!はself.= (self.collect_ref)と同じ
  • mapはself.deep_copy.map!と同じ
  • each!は無い。eachは単なる走査
  • Range.mapするとRange.deep_copyがArrayを返すのでArrayが返る
  • 1..3.collect_ref(`x[x])してもNumber.derefがコピーを返すので戻り値は{1 2 3}になる
  • Range.= v は、Range..= (v.)になるのでRange.collect!はそれっぽく動作する

//each
[v:: 0 1..100.each& `n[v.+= n] v].assert(5050)
[v:: 0 1..100.each& 2, `n1 n2[v.+= n1] v].assert(2500)
[v:: 0 1..100.each& 100..(200), `n1 n2[v.+= n1.+= n2] v].assert(20000)
[v:: 0 1..100.each& 100..(200), 2, `n11 n21 n12 n22[v.+= n11.+= n22] v].assert(10000)

//collect
['abc'.collect& `c[c.inc]].assert(`x[x.== {\b \c \d}.&& [x.type?(:Array)]])
['abc'.collect& 'def', `c1 c2[c2.- c1]].assert({3 3 3})
['abcdef'.collect& 2, `c1 c2[c1]].assert({\a \c \e})

//map
['abc'.map& `c[c.inc]].assert(`x[x.== 'bcd'.&& [x.type?(:String)]])
['abc'.map& 'def', `c1 c2[c2.- c1]].assert("\x3\x3\x3")
['abcdef'.map& 3, `c1 c2 c3[c1]].assert('abaded')