Rubyのシンタックス勉強用（配列や繰り返し処理 編）

Rubyのシンタックスを息を吸うように書くために、少しでも理解が怪しいシンタックスを繰り返したくために書きます。

（どんどん更新していきます）

# メソッドの可変長引数

個数に制限のない可変長引数を使って、以下の結果が得られるように記述してください。
文字列の配列も簡潔に作成できる処理を書きましょう。

```
"こんにちは！TOMとJEFFとJAFさん"
```

## 正解

```ruby
GREET = 'こんにちは'
member = %w(TOM JEFF JAF)

def greeting(greet, *names)
  "#{greet}！#{names.join('と')}さん"
end

p greeting(GREET, member)
```

参考: [プロを目指す人のためのRuby入門_119p](https://ruby-book.jnito.com/)

# 文字列を配列に変換する

文字列中にある任意の文字列（','）で区切って、以下のような配列を作ってください。

```
["Tokyo", "Saitama", "Chiba", "Miyagi"]
```

## 正解

```ruby
p 'Tokyo,Saitama,Chiba,Miyagi'.split(',')
```

参考: [プロを目指す人のためのRuby入門_121p](https://ruby-book.jnito.com/)

# 配列に初期値を設定


`Array.new`に引数に数を入れて、数の分だけブロック中のスクリプトを実行しましょう。
ブロック中のコードは、 3で割った値を出力する。

return

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

## 正解

```ruby
p Array.new(10) { |n| n % 3 + 1 }
```

参考: [プロを目指す人のためのRuby入門_122p](https://ruby-book.jnito.com/)

# 添字（index番号）の付いた繰り返し処理

以下を返すような、添字（index番号）の付いた繰り返し処理を書きましょう。

return

```
"No.0 is TOM"
"No.1 is JEFF"
"No.2 is JAF"
```

## 正解

```ruby
members = %w(TOM JEFF JAF)
members.each_with_index { |member, i| p "No.#{i} is #{member}" }
```

第二引数に、index番号が入るわけですね。

参考: [プロを目指す人のためのRuby入門_125p](https://ruby-book.jnito.com/)

# 添字（index番号）を指定して、繰り返し処理をしたい場合

以下を返すような、添字（index番号）を指定して、繰り返し処理を書きましょう。

return

```
"No.1 is TOM"
"No.2 is JEFF"
"No.3 is JAF"
```

## 正解

```ruby
members = %w(TOM JEFF JAF)
members.each.with_index(1) { |member, i| p "No.#{i} is #{member}" }
members.each_with_index { |member, i| p "No.#{i + 1} is #{member}" }
```

参考: [プロを目指す人のためのRuby入門_125p](https://ruby-book.jnito.com/)

# 添字（index番号）をつけて、繰り返し処理をした結果を配列として返したい

以下を返すような、処理を書きましょう。

return

```
["No.0 is TOM", "No.1 is JEFF", "No.2 is JAF"]
```

## 正解

```ruby
members = %w(TOM JEFF JAF)
p members.map.with_index { |member, i| "No.#{i} is #{member}" }
```

参考: [プロを目指す人のためのRuby入門_126p](https://ruby-book.jnito.com/)

# 特定文字が含まれる要素を削除する繰り返し処理

```
members = %w(TOM JEFF JAF)
```

の要素から、文字列`F`を含む要素を削除する処理を書きましょう。

return

```
["TOM"]
```

## 正解

```ruby
members = %w(TOM JEFF JAF)
p members.delete_if.with_index { | member,i | member.include?('F') }
```

`delete_if`メソッドは、要素の数だけ繰り返しブロックを実行し、ブロックの戻り値が真になった要素を削除します。

参考: [プロを目指す人のためのRuby入門_126p](https://ruby-book.jnito.com/)

# 補足説明（Enumeratorクラスについて）

まず、Enumeratorの読み方ですが、イニューマラブルと呼びます。

上記で紹介していた、要素とインデックス番号をブロックに渡して繰り返し処理する`with_index`はEnumeratorクラスのインスタンスメソッドです。

http://doc.okkez.net/2.0.0/view/method/Enumerable/i/each_with_index

# 配列がブロック引数に渡された場合の挙動

前提

```
scores = [
  # [英語,数学,科学]
  [50,80,60], # Aさん
  [40,90,70], # Bさん
  [60,90,80], # Cさん
  [90,50,90], # Dさん
]
```

ある四人の三科目ごとのテスト結果から、各々の合計得点を求める処理を書きましょう。
各人の合計点を配列として出力してください。

return

```
[190, 200, 230, 230]
```

## 正解

```ruby
scores = [
  # [英語,数学,科学]
  [50,80,60], # Aさん
  [40,90,70], # Bさん
  [60,90,80], # Cさん
  [90,50,90], # Dさん
]

total_scores = []

scores.each do |score|
  english = score[0]
  math = score[1]
  science = score[2]
  total_scores << english + math + science
end

p total_scores
```

## 正解 2

ちなみに、ブロック引数を教科の数だけ用意すると、各カラムごとの値を取得でき、コード自体もスッキリします。

```ruby
scores = [
  # [英語,数学,科学]
  [50,80,60], # Aさん
  [40,90,70], # Bさん
  [60,90,80], # Cさん
  [90,50,90], # Dさん
]

total_scores = []

scores.each do |english, math, science|
  total_scores << english + math + science
end

p total_scores
```

参考: [プロを目指す人のためのRuby入門_127p](https://ruby-book.jnito.com/)

# 配列とインデックス番号をブロック引数に含めて渡した場合の挙動

ある四人の三科目のテスト結果をそれぞれ出力する処理を書きましょう。
その際、インデックス番号をつけて以下のように吐き出されるよう処理を書きましょう。

return

```
"No.1番 英語 => 50点, 数学 => 80点, 科学 => 60点"
"No.2番 英語 => 40点, 数学 => 90点, 科学 => 70点"
"No.3番 英語 => 60点, 数学 => 90点, 科学 => 80点"
"No.4番 英語 => 90点, 数学 => 50点, 科学 => 90点"
```

## 正解

```ruby
scores = [
  # [英語,数学,科学]
  [50,80,60], # Aさん
  [40,90,70], # Bさん
  [60,90,80], # Cさん
  [90,50,90], # Dさん
]

scores.each.with_index(1) do |(english, math, science), i|
  p "No.#{i}番 英語 => #{english}点, 数学 => #{math}点, 科学 => #{science}点"
end
```

ポイントは、配列の要素を受け取るブロック引数をカッコ`()`で囲むと、配列の要素を別々の引数として、受け取ってくれます。

```ruby
scores.each.with_index(1) do |english, math, science, i|
  p "No.#{i}番 英語 => #{english}点, 数学 => #{math}点, 科学 => #{science}点"
end
```

上記のように、カッコをつけないと、最初のブロック引数（`english`）に、配列ごと渡ってしまうので、注意が必要です。

```
"No.番 英語 => [50, 80, 60]点, 数学 => 1点, 科学 => 点"
"No.番 英語 => [40, 90, 70]点, 数学 => 2点, 科学 => 点"
"No.番 英語 => [60, 90, 80]点, 数学 => 3点, 科学 => 点"
"No.番 英語 => [90, 50, 90]点, 数学 => 4点, 科学 => 点"
```

# 補足説明（配列操作できる色々なメソッドについて）

配列を操作するためのメソッドは、自作する前に豊富なメソッド群を調べてみましょう。

配列のメソッドは主に以下にあるでしょう

- Arrayクラス自身に定義されているやつ
    - https://docs.ruby-lang.org/ja/latest/class/Array.html
- Enumerableモジュールに定義されているやつ
    - https://docs.ruby-lang.org/ja/latest/class/Enumerable.html

# 補足説明（Enumeratorクラスについて）

まず、Enumeratorの読み方ですが、イニューマラブルと呼びます。

上記で紹介していた、要素とインデックス番号をブロックに渡して繰り返し処理する`with_index`はEnumeratorクラスのインスタンスメソッドです。

http://doc.okkez.net/2.0.0/view/method/Enumerable/i/each_with_index

# 3問同時出題、繰り返し処理

最適なメソッドを選んでコードを書いてください。

```
- 問１ : 10回繰り返すだけのメソッドを用いて、0から1をどんどん足してください
    - 期待する戻り値 => 10
- 問2 : 10から20まで1を足していった全結果を配列で返す繰り返しメソッドを書いてください
    - 期待する戻り値 => [10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
- 問3 : 10から30まで2を足していった全結果を配列で返す繰り返しメソッドを書いてください
    - 期待する戻り値 => [10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30]
```

## 正解

```ruby
# 問１
sum = 0
p 10.times { sum += 1 }

# 問2
a = []
10.upto(20) { |n| a << n }
p a

# 問3
a = []
10.step(30, 2) { |n| a << n }
p a
```