読者です 読者をやめる 読者になる 読者になる

まりぴよこのブログ

日々の日記。技術ネタでまとまりきってないものの記録、伝わる文章の書き方を練習とか。

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つの配列を連結した新しい配列を作成して返します」そうな。

参考:

qiita.com

実は今ひとつしっくりきてないところがある

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のがしっくりくるペアみたいですね〜

次はそっちにしよう。。