Rubyの勉強(落ち葉拾いその1)Arrayの扱い
Rubyの基本中の基本、Array
変なところでハマった・・
Arrayに要素を追加するメソッド
- push
- <<
- concat
は、元の配列を操作する「破壊的メソッド」である。(と言うことを知らなかった)
やりたいこと
配列にある数値の合計値を計算して、配列の一番後ろの要素として加えたい。
input = [ 1, 2, 3] # こんなんが返ってくることを期待 => [ 1, 2, 3, 6]
問題あり解法
<< を使って合計値を末尾に追加しようとした
def sum_up_list (input) input << input.inject(&:+) end
あれ??
input = [ 1, 2, 3] sum_up_list(input) puts input # => [ 1, 2, 3, 6 ] sum_up_list(input) puts input # => [ 1, 2, 3, 6, 12 ]
どんどん増えてる・・・
他の要素追加系メソッド同じ感じ・・
- push
- <<
- concat
全部呼び出し元の配列を操作するメソッド
RSpecでテスト呼び出す度にどんどん input
配列が大きくなっていく;;
新しい配列を作成して返して欲しい場合
- +を使う
def sum_up_list (input) sum = input.inject(&:+) input + [sum] # ココ! end
こうすると元のinput配列は操作されず、新しい配列が戻される。 +は「2つの配列を連結した新しい配列を作成して返します」そうな。
参考:
実は今ひとつしっくりきてないところがある
sum_up_listで合計値を出して、その数値を1つ配列に加えたいんだけど、 +で連結できるが配列同士のため、
[]を使って数値を配列に変換している。。
前回書いたコードで、自分的にイマイチなんじゃないかと気になっているコード
def self.append_sum_to_last(list) sum = list.inject(&:+) list + [sum] end
コレで良いんだろうか・・・・
pushみたいに1個要素を付け加えるだけでいいんだけどな・・・
余談・・
mapの使い方調べてて、こんな記事を発見。
Rubyist Magazine - map と collect、reduce と inject ―― 名前の違いに見る発想の違い
- map, reduce
- collect, inject
派があるそうです。。
なんとなくうろ覚えで、mapとinjectを使ってしまった私・・ (reduce, collectは存在を知らず) 変なとこで混ぜてて、ポリシー無いヤツ感満載だったのかしら・・とか思いました。
mapは有名だから知ってたけど、確か配列縮める系のやつあったような・・injectだったかな?というレベルで思い出して、使ったんだけど、map, reduceのがしっくりくるペアみたいですね〜
次はそっちにしよう。。