Ruby初心者の繰り返し処理基礎まとめ

# 繰り返し処理(ループ)とは
- 繰り返し処理とは、決まった回数や条件を満たしているは同じ処理を繰り返し行う場合に使います。 
- Rubyの繰り返し処理は配列やハッシュのメソッドなどの、制御構造内での繰り返し処理や、ブロック付きメソッド呼び出しという制御構造を定義する事ができるものまで多くの種類があります。
- 今回はその中でよく使う４つを簡略的に紹介します。
## `each`メソッド
`each`メソッドはRubyにおいて非常にメジャーな繰り返し処理の1つであり、配列やハッシュなどのコレクションオブジェクトを操作する際によく使われます。
- `each`メソッド　構文
  ```ruby
  collection.each do |変数|
    # 処理
  end
  ```
  ここでの`collection`は繰り返し処理を行う対象となるオブジェクトで、`変数`はブロック内の`do ~ end`で各要素を受け取るための変数名です。
  - 配列を対象とした`each`の例
    ```ruby
    fruits = ["apple", "banana", "orange"]
    fruits.each do |fruit|
      puts fruit
    end
    ```
    このコードでは`fruits`配列の各要素を`fruit`という変数に代入して、`puts`メソッドで出力しています。
    ```ruby:出力
    apple
    banana
    orange
    ```
### `each_with_index`メソッド
- `each`メソッドの派生で`each_with_index`メソッドというのがあります。
    `each`メソッドと同様に繰り返しの処理を行いつつ、各要素のインデックスも同時に受け取ることができます。
  ```ruby:each_with_index
  collection.each_with_index do |item, index|
      # ブロックでの処理
  end
  ```
    `collection`に繰り返し処理を行いたい配列やハッシュなどを指定し、ブロック内での`item`には配列の要素やハッシュの値、`index`には配列のインデックスやハッシュのキーが渡されます。
  ```ruby:each_with_index
  fruits = ['apple', 'banana', 'orange']
  fruits.each_with_index do |fruit, i|
    puts "#{i}: #{fruit}"
  end
  ```
  このコードを実行すると以下の様に出力されるが、インデックス番号は0から始まっている。
  ```ruby:出力
  0: apple
  1: banana
  2: orange
  ```
  この番号を`each_with_index`メソッドの第２引数に、インデックス番号の開始値を指定することで番号を任意の位置から始める事ができます。
  ```ruby:each_with_index(1)
  fruits = ['apple', 'banana', 'orange']

  fruits.each_with_index(1) do |fruit, index|
    puts "#{index}: #{fruit}"
  end
  #出力結果
  #=> 1: apple
  #=> 2: banana
  #=> 3: orange
  ```
## `times`メソッド
`times`メソッドは整数オブジェクトに対して利用でき、指定した回数だけ繰り返し処理を実行するメソッドです。
- `times`メソッド　構文
  ```ruby:times構文
  回数.times do |変数|
  # 繰り返したい処理
  end
  #または
  回数.times { |変数|
  # 繰り返したい処理
  }
  ``` 
  `回数`には繰り返し回数を指定し、ブロック内の処理が指定した回数文繰り返されます。ブロック内には繰り返し処理で使用するための`変数`を定義する事ができます。
`変数`の部分は省略可能で、以下の様に簡略化して書くこともできます。
  
  ```ruby:
  3.times do
    puts "Hello, world!"
  end
  #=> Hello, world!
  #=> Hello, world!
  #=> Hello, world!
  ```
  ただし、`times`メソッドの`ブロック変数`には繰り返し処理が現在何回目であるかを示す数値が自動的に格納されます。
  ```ruby
  3.times do |i|
    puts "Hello, world! #{i + 1}"
  end
  #=> Hello, world! 1
  #=> Hello, world! 2
  #=> Hello, world! 3
  ```
  `puts`文内で`i + 1`とすることで、出力されるテキストの末尾に現在の繰り返し回数を追加しています。

## `map`メソッド
`map`メソッドは配列や範囲オブジェクトの要素を変換するために使用されるメソッドです。元の配列を変更するのではなく、変換された新しい配列を返します。
また、`map`メソッドは要素ごとにブロックを実行し、ブロックの戻り値を配列に格納します。
- `map`メソッド　構文
  ```ruby:map 構文
  array.map { |item| block }
  ```
  上記の`array`は変換したい配列を指定しています。
`item`は配列の各要素がブロックに渡される際の引数で、`block`は配列の各要素に対して実行されるブロックです。
`map`メソッドはブロックの戻り値を新しい配列の要素として格納してその配列を返します。
  ```ruby:mapメソッドの例
  arr = [1, 2, 3, 4, 5]
  new_arr = arr.map { |n| n * 2 }
  puts new_arr # => [2, 4, 6, 8, 10]
  ```
  上記の例では`arr`という配列の各要素に対して２倍した新しい配列を作成している。`map`メソッド内の`n * 2`によって各要素を２倍して、新しい配列である`new_arr`に代入している。

   `map`メソッドは他のメソッドと組み合わせて使用することができて便利です。
  後述する`select`メソッドとの併用もでき、`map`メソッドで配列の要素を変更した新しい配列を作成したあと、`select`メソッドを使って条件に一致する要素だけを抽出する事もできます。
  - `map`と`select`を組み合わせて、配列から条件に合う要素だけを抜き出す。
    ```ruby
    numbers = [1, 2, 3, 4, 5, 6]
    even_numbers = numbers.select { |n| n.even? } 
    # => [2, 4, 6]
    squared_even_numbers = even_numbers.map { |n| n**2 } 
    # => [4, 16, 36]
    ```
  - `map`と`reduce`を組み合わせて、配列の各要素を処理し、その結果を合算する。
    ```ruby
    numbers = [1, 2, 3, 4, 5]
    sum_of_squares = numbers.map { |n| n**2 }.reduce(0) { |sum, n| sum+ n } 
    # => 55
    ```
  - `map`と`with_index`を組み合わせて、配列の各要素に対して、そのインデックス番号も一緒に扱う。
    ```ruby
    fruits = ["apple", "banana", "orange"]
    fruits_with_index = fruits.map.with_index { |f, i| "#{i}: #{f}" }
    # => ["0: apple", "1: banana", "2: orange"]
    ```

## `while`文
`while`文は、指定された条件式が`true`の時に繰り返し処理を行う制御構造です。条件式が`false`になると、while文を抜けて次の処理に進みます。条件式が一度も`false`にならずに永遠にループすることもあります。
- `while`文　構文
  ```ruby:while 構文
  while 条件式 do
    # 繰り返したい処理
  end
  ```
  `while`文は条件を満たしている限り何度も同じ処理を繰り返すので、データの処理をすべてのデータが処理されるまで繰り返したい場合などに使えます。
  ```ruby
  i = 1
  while i <= 10 do
    puts i
    i += 1
  end
  ```
  上記の例では、変数`i`が１から１０になるまで繰り返し処理を行っています。
  `i`が１０になると条件式の`i <= 10`が`false`となるので、`while`文を抜けて次の処理に進みます。
  ```:出力
  1
  2
  3
  4
  5
  6
  7
  8
  9
  10
  ```
- `while`文ではループを行う際に、条件式が常に`true`にならないようにループ内で条件式が変更されるようにする必要があります。
  そうでないと、無限ループに陥り条件を抜け出せなくなる可能性があります。
- `while`文の条件式は、比較演算子などを用いて真偽値を返すようにします。
- 以上の点を踏まえて`while`文を使用する際は条件式がどのようなときにループを終了するか、あらかじめ明確に決めておく必要があります。

## まとめ
この記事では、繰り返し処理を行う場面でよく使うものを紹介しました。

Rubyでは基本的に`each`を使うのがメジャーらしいので、仕組みを理解してマスターしていこうと思いました。

`map`メソッドについては繰り返し処理とは違った内容になってしまいましたが、よく使う繰り返し処理と合わせて便利なメソッドなのでそのまま勢いで載せてしまいました。

次は繰り返し処理を行う上で必要な`break`の概要と使い方と使用例、注意事項などをまとめてみたいと思います。

はじめての投稿で拙いところもあると思いますが、自分と同じくRuby初学者の為になれば幸いです。