大ちゃんの駆け出し技術ブログ

RUNTEQ受講生のかわいいといわれるアウトプットブログ

【無職に転生 ~ 就職するまで毎日ブログ出す_23】【Ruby】Arrayの演算

はじめに

こんにちは、大ちゃんの駆け出し技術ブログです。

タイトルにあるとおり【無職に転生 ~ 就職するまで毎日ブログ出す】というチャレンジをしています!!!!昨日までは就活するまで本気出すでしたが、これだとまるで就活後は頑張らないのかと思われてしまいそうで、、、大人気アニメのタイトルのまるパクリチャレンジです。

https://i.gyazo.com/3a02b7aae4e5e538130d4bb199b55dc7.png

RailsやらRubyやらSQLやらその他Webの知識やらが色々と抜け落ちているのを感じており、知識の定着のためにもアウトプットする機会を増やすためです。加えて、退職して文字通り無職に転生しましてプロニートになり、毎日時間に余裕ができたので引き締めるためにも毎日投稿を思い至りました!

【投稿内容】

  • SQLの難しい処理 (副問合せ、JOINとか複雑な処理が書けない)
  • Rails全般 (純粋に必要な知識が多すぎる、網羅的な理解が足りない)
  • Rubyのあまり使わないメソッドや記述方法 (あまり重要ではないけど特に)
  • Web知識全般 (クッキーやら、セッションやらなんとなくで理解しているものの自分の言葉で説明できない)
  • 書籍 (スタートアップ企業に勤めるので、自分が会社に与える影響やパフォーマンスを高めるためビジネス書を読んでいきます。)

本日やること

配列にまつわる演算に関してうろ覚えな部分が多かったのでアウトプットします。Arrayクラスは足し算や引き算などをすることができ、組み合わせによって異なる挙動を出します。最後にはちょっとした問題も用意しているので是非解いてみてください!

加算

足し算の場合、お互いの要素を結合させた配列になります。

a = [1,2,3,4,5]
b = [4,5,6,7,8]
a + b
=> [1, 2, 3, 4, 5, 4, 5, 6, 7, 8]

これと似たような挙動としてconcatメソッドがあります。しかし、concatを使用した場合レシーバーである配列は結合された配列の値になります。つまり、破壊的メソッドとなります。

a.concat(b)
=> [1, 2, 3, 4, 5, 4, 5, 6, 7, 8]
a
=> [1, 2, 3, 4, 5, 4, 5, 6, 7, 8]

下記の記述でconcatと同じように破壊的な処理を行うこともできます。

a += b

減算

引き算の場合、共通する要素を配列から取り除いた配列を返却します。

a = [1,2,3,4,5]
b = [4,5,6,7,8]
a - b
=> [1, 2, 3]
b - a
=> [6, 7, 8]

全く同じ要素であれば配列の順番を無視して共通の要素が取り除かれます。また、要素の組み合わせが全て一致している場合、空の配列を返します。

c = [4,5,2,3,1]
=> [4, 5, 2, 3, 1]
a - c
=> []

乗算

掛け算の場合、配列同士の掛け算をすることはできません。

a = [1,2,3,4,5]
b = [4,5,6,7,8]
a * b
# (no implicit conversion of Array into Integer)

しかし、Arrayに対して数字を掛け算することで、中の要素をその数字の数分だけ複製します。

a * 2
=> [1, 2, 3, 4, 5, 1, 2, 3, 4, 5]
a * 5
=> [1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5]

配列の中の要素の型は関係ないため、数字でもすべてnil大丈夫です。

d = %w(1 2 3 4 5)
=> ["1", "2", "3", "4", "5"]
d * 2
=> ["1", "2", "3", "4", "5", "1", "2", "3", "4", "5"]
e = [nil,nil,nil]
=> [nil, nil, nil]
e * 3
=> [nil, nil, nil, nil, nil, nil, nil, nil, nil]

除算

配列は割り算をすることができません。undefined methodからArrayクラスには/をそもそも使うことができないようになっています。

a / b
# (undefined method `/' for [1, 2, 3, 4, 5]:Array)
a / 2
# (undefined method `/' for [1, 2, 3, 4, 5]:Array)

和集合

和集合は|で表すことができます。お互いの要素の中で重複していない要素を組み合わせた配列を出力します。

a = [1,2,3,4,5]
b = [4,5,6,7,8]
a | b
=> [1, 2, 3, 4, 5, 6, 7, 8]

配列を加算した後に重複している要素を取り除くuniqメソッドで同一の処理を行うことができます。

(a + b).uniq
=> [1, 2, 3, 4, 5, 6, 7, 8]

破壊的な処理は下記メソッドで行えます。

a |= b
=> [1, 2, 3, 4, 5, 6, 7, 8]

積集合

積集合は&で表すことができます。お互いの重複している要素を組み合わせ配列を出力します。

a = [1,2,3,4,5]
b = [4,5,6,7,8]
a & b
=> [4, 5]

問題

上記の基本を踏まえた上でちょっと問題をいくつか用意したので解いてみてください。

第一問

a=[1,2,3]
b=[1,2,3]
c=[1,2,3]

a + b + c

第二問

a = [1,2,3,4,5]
b = [4,5,6,7,8]

b * 2 + a

第三問

a=[1,2,3]
b=[1,2,3]
c=[1,2,3]

a + b | c

第四問

a=[1,2,3]
b=[4,5,6]
c=[7,8,9]

a+b+c+(a.concat(b +  c)) | a

回答

第一問

[1, 2, 3, 1, 2, 3, 1, 2, 3]

解説は不要かなと思います。

第二問

[4, 5, 6, 7, 8, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5]

掛け算は先に実行されるのでb * 2から先に実行され、その後aが加算されます。。

第三問

[1,2,3]

これはちょっとした捻くれ問題でした。和集合は実は+より後に実行されます。よって最初に加算が実行されます。

[1,2,3,1,2,3] | c

その後お互いの要素で重複していない要素を出力します。

第四問

 [1, 2, 3, 4, 5, 6, 7, 8, 9]

これは最後にある | aに着目すれば大丈夫ですね。a+b+c+(a.concat(b + c))の中の要素は必ず1,b,cの要素が全てあり、a との和集合ですので全ての重複していない要素が取り出されます。