配列の基礎的なメソッド集【Ruby超入門】

#配列
配列は複数のデータをまとめて格納できるオブジェクト。
配列内の要素は順番に並んでいて、添え字（インデックス）を指定することでそのデータを取り出すことができる。

* 配列は`[]`の中にカンマ区切りで複数のオブジェクトを書いていく。
* 中身が無い場合は空の配列ができる。
* 種類の違うオブジェクトも入れられる。
* 変数に代入する場合は複数形で命名する。

**関連記事**
[命名規則【Ruby超入門】](https://qiita.com/yyykms123/items/7ef44e2a289a443a1101)

##配列の要素を取得
**配列は変数の後に`[n]`などのインデックス番号をつけることで取得できます。**
この`[n]`の中のインデックス番号は配列の先頭からを示しているのですが、注意としては**0番目から始まる**ということです。
1番目の`'コーヒー'`は`[0]`で、3番目の`'ティーラテ'`は`[2]`となります。

```rb
drinks = ['コーヒー', 'カフェラテ', 'ティーラテ']
puts drinks[0]  #=> 'コーヒー'
puts drinks[2]  #=> 'ティーラテ'
```

`[n]`の番号に`-`（マイナス）をつけることで後ろの要素から取得できます。

```rb
drinks = ['コーヒー', 'カフェラテ', 'ティーラテ']
puts drinks[-1]  #=> 'ティーラテ'
puts drinks[-2]  #=> 'カフェラテ'
```

要素以上の番号で指定した場合は`nil`が帰ってきます。`nil`は「何もない」ことを表すオブジェクトです。

```rb
drinks = ['コーヒー', 'カフェラテ', 'ティーラテ']
puts drinks[3]  #=> nil
```

##基本的なメソッド

###first、last
`first`メソッドは`[0]`と同じで、**配列の先頭の要素を取得するメソッドです。**
`last`メソッドは`[-1]`と同じで、**配列の末尾の要素を取得するメソッドです。**

```rb
drinks = ['コーヒー', 'カフェラテ', 'ティーラテ']
puts drinks.first  #=> 'コーヒー'
puts drinks.last  #=> 'ティーラテ'
```

###push、unshift
`push`メソッドは**配列の末尾へ要素を追加するメソッドです。**
**`<<`でも末尾へ要素を追加できます。**
`unshift`メソッドは**配列の先頭に要素を追加するメソッドです。**

```rb
drinks = ['コーヒー']
drinks.push('カフェラテ')
p drinks
#=> ['コーヒー', 'カフェラテ' ]
drinks.unshift('モカ')
p drinks
#=> ['モカ', 'コーヒー', 'カフェラテ']
drinks << 'ティーラテ'
p drinks
#=> ['モカ', 'コーヒー', 'カフェラテ', 'ティーラテ']
```

###pop、shift
`pop`メソッドは**配列の末尾から要素を1つ削除するメソッドです。**
`shift`メソッドは**配列の先頭から要素を1つ削除するメソッドです。**

```rb
drinks = ['モカ', 'コーヒー', 'カフェラテ']
drinks.pop
p drinks  #=> ['モカ', 'コーヒー']
drinks.shift
p drinks  #=> ['コーヒー']
```

なお`pop`メソッドと`shift`メソッドは、削除した要素を返します。

```rb
drinks = ['モカ', 'コーヒー', 'カフェラテ']
p drinks.pop  #=> 'カフェラテ'
p drinks.shift  #=>  'モカ'
```

##配列の足し算と引き算

###足し算
**配列で足し算をすると、2つの配列をつなげて新しい配列を作ります。**

```rb
a = [1, 2, 3]
b = [4, 5]
p a + b  #=> [1, 2, 3, 4, 5]

drinks_a = ['モカ', 'コーヒー']
drinks_b = ['カフェラテ', 'ティーラテ']
p drinks_a + drinks_b
#=> ['モカ', 'コーヒー', 'カフェラテ', 'ティーラテ']
```

###引き算
**配列で引き算をすると、元の配列から要素を取り除いた新しい配列を作ります。**
引き算は配列aと配列bを比べて、配列aにだけある要素を得ることができます。

```rb
a = [1, 2, 3]
b = [1, 3, 5]
p a - b  #=> [2]

drinks_a = ['モカ', 'コーヒー', 'カフェラテ', 'ティーラテ']
drinks_b = ['モカ', 'ティーラテ']
p drinks_a - drinks_b  #=> ['コーヒー', 'カフェラテ']
```

##便利なメソッド

* `size`メソッド
* `sum`メソッド
* `uniq`メソッド
* `sample`メソッド
* `shuffle`メソッド
* `sort`メソッド
* `join`メソッド
* `split`メソッド

###配列の要素数を得る(sizeメソッド)

`size`メソッドは**配列の要素数を返す。**

```ruby
puts [1, 2, 3].size  #=> 3
```

###配列の全要素の合計を得る(sumメソッド)

`sum`メソッドは**配列の全要素を足した値を返す。**

```ruby
puts [1, 2, 3].sum  #=> 6
```

先ほどの`sum`メソッドと組み合わせると平均値の計算ができる。

```ruby
a = [1, 2, 3]
puts a.sum / a.size  #=> 2
```

###配列の重複している要素を取り除く(uniqメソッド)

`uniq`メソッドは**重複している要素を取り除いた配列を返す。**

```ruby
p [1, 3, 2, 2, 3].uniq  #=> [1, 3, 2]
```

###配列の要素をランダムに取得する(sampleメソッド)

`sample`メソッドは**配列の要素を1個ランダムに選んで返す。**

```ruby
puts [1, 2, 3].sample  #=> 2
```

引数を指定した場合は要素数を超えない範囲で取得する。

```ruby
p [1, 2, 3, 4].sample(2)  #=> [1, 3]
```

###配列の要素をランダムに並び替える(shuffleメソッド)

`shuffle`メソッドは**配列の要素をランダムに並び替える。**

```ruby
p [1, 2, 3].shuffle  #=> [3, 1, 2]
```

###配列の要素を順番に並び替える(sortメソッド)

`sort`メソッドは**配列の要素を順番に並び替える。**

```ruby
p [3, 1, 2].sort  #=> [1, 2, 3]
```

配列の要素が数値の時は小さい順に並び替えて、文字列の時はabc順に並び替えられる。

また文字列は先頭の文字で比較し、同じであれば２文字目と比較していく。
大文字が混じると「大文字が先、小文字が後」となる。

```ruby
p ['yuki', 'tama', 'aki'].sort
#=> ['aki', 'tama', 'yuki']
p ['yuki', 'aya', 'aki'].sort
#=> ['aki', 'aya', 'yuki']
p ['aya', 'aki', 'Tama'].sort
#=> ['Tama', 'aki', 'aya']
```

**`reverse`メソッドを使うと並び順を逆にできる**

```ruby
p [3, 1, 2].sort.revers  #=> [3, 2, 1]
```

###配列中の文字列を連結する(joinメソッド)

`join`メソッドは**配列中の文字列を連結する。**
引数を指定すると、要素の間に指定した引数を入れて連結する。

```ruby
puts ['カフェラテ', 'チーズケーキ', 'バニラアイス'].join
#=> カフェラテチーズケーキバニラアイス
puts ['カフェラテ', 'チーズケーキ', 'バニラアイス'].join('と')
#=> カフェラテとチーズケーキとバニラアイス
```

###配列中の文字列を分割する(splitメソッド)

`split`メソッドは**スペース区切りになっている文字列を配列にして返す。**
引数を指定すると、スペース以外の文字にも対応できる。

```ruby
puts 'カフェラテ チーズケーキ バニラアイス'.split
#=> ['カフェラテ', 'チーズケーキ', 'バニラアイス']
puts 'カフェラテとチーズケーキとバニラアイス'.split('と')
#=> ['カフェラテ', 'チーズケーキ', 'バニラアイス']
```

##ブロックを使う配列のメソッド

例として使用頻度の高いメソッドを挙げていく

* `each`メソッド
* `map`メソッド
* `select`メソッド/`reject`メソッド
* `find`メソッド

###配列の繰り返し処理(eachメソッド)

**`do`から`end`までを「ブロック」と呼び、その中で配列を順番に繰り返す。**
`each`メソッドの役割は配列の要素を最初から最後まで順番に取り出すことだが、取り出した要素をどう扱うかは、ブロック内の処理に記述する。

```ruby
numbers = [1, 2, 3]
numbers.each do |n|
  puts n
end

#=> 1
#=> 2
#=> 3
```

またブロックは以下のように1行で書くこともできる。

```ruby
numbers = [1, 2, 3]
numbers.each { |n| puts n }

#=> 1
#=> 2
#=> 3
```

###配列の各要素を変換(mapメソッド)

`map`メソッドは**配列の各要素へ処理を行い、結果を新しい配列にして返す。**

例とて配列の各要素を10倍にした新しい配列を作る。

```ruby
numbers = [1, 2, 3, 4, 5]
new_numbers = []
numbers.map { |n| new_numbers << n * 10 }

p new_numbers  #=> [10, 20, 30, 40, 50]
```

`map`メソッドを使うとブロックの戻り値が配列の要素となる新しい配列が作成されるため、`map`メソッドの戻り値をそのまま新しい変数に入れることができる。

```ruby
numbers = [1, 2, 3, 4, 5]
# ブロックの戻り値が新しい配列の各要素になる
new_numbers = numbers.map { |n| n * 10 }

p new_numbers  #=> [10, 20, 30, 40, 50] 
```

###配列の各要素を真偽値によって変換(selectメソッド/rejectメソッド)

`select`メソッドは**ブロックの戻り値が真（true）の要素を返し、新しい配列を作る。**

```ruby
numbers = [1, 2, 3, 4, 5, 6]
# ブロックの戻り値が真になった要素だけが集められる
even_numbers = numbers.select { |n| n.even? }

p even_numbers  #=> [2, 4, 6]
```

`reject`メソッドは`select`メソッドの反対で、**ブロックの戻り値が偽（false）の要素を返し、新しい配列を作る。**

```ruby
numbers = [1, 2, 3, 4, 5, 6]
# 3の倍数を除外する（3の倍数以外を集める）
non_multiples_of_three = numbers.reject { |n| n % 3 === 0 }

p non_multiples_of_three  #=> [1, 2, 4, 5]
```

###配列の最初の要素を真偽値によって変換(findメソッド)

`find`メソッドは**ブロックの戻り値が真（true）になった最初の要素を返す。**

```ruby
numbers = [1, 2, 3, 4, 5, 6]
# ブロックの戻り値が最初に真になった要素を返す
even_numbers = numbers.find { |n| n.even? }

p even_numbers  #=> 2
```

###ブロックを簡潔に書く(&:)

`map`メソッドや`select`メソッドなどにブロックを渡す代わりに、`&:`メソッド名といった引数を渡せば、ブロックを簡潔に書くことができる。

ただし以下の条件が揃った時のみ。

**1. ブロック引数が1個だけである。
2. ブロックの中で呼び出すメソッドには引数がない。
3. ブロックの中では、ブロック引数に対してメソッドを1回呼び出す以外の処理がない。**

```ruby
# このコードは、
['ruby', 'java', 'perl'].map { |s| s.upcase }
#=> ['RUBY', 'JAVA', 'PERL']

# こう書き換えられる
['ruby', 'java', 'perl'].map(&:upcase)
#=> ['RUBY', 'JAVA', 'PERL']


# このコードは、
[1, 2, 3, 4, 5, 6].select { |n| n.odd? }
#=> [1, 3, 5]

# こう書き換えられる
[1, 2, 3, 4, 5, 6].select(&:odd?)
#=> [1, 3, 5]
```

##参考書
* [プロを目指す人のためのRuby入門](https://www.amazon.co.jp/gp/product/4774193976/ref=as_li_tl?ie=UTF8&camp=247&creative=1211&creativeASIN=4774193976&linkCode=as2&tag=ykms1230e-22&linkId=7d182a6724516a0f1a495c33599a4946)
* [ゼロからわかる Ruby 超入門 (かんたんIT基礎講座)](https://www.amazon.co.jp/gp/product/4297101238/ref=as_li_tl?ie=UTF8&camp=247&creative=1211&creativeASIN=4297101238&linkCode=as2&tag=ykms1230e-22&linkId=16f1470f0d06b61a190643877fd54da0)