[振り返り用] Rubyの繰り返し (ループ) 処理 全網羅まとめ - 実務での具体例付き

# はじめに
株式会社シンシアでは、実務未経験のエンジニアの方や学生エンジニアインターンを採用し一緒に働いています。
※ シンシアにおける働き方の様子はこちら

https://www.wantedly.com/companies/xincere-inc/stories

弊社には年間100人程度の実務未経験の方に応募いただき、技術面接を実施しております。
その時に、Ruby で繰り返し処理について質問をいただいたので、記事にもまとめておきます。

Rubyには繰り返し処理（ループ）を書くための手段が非常に豊富に存在します。  
この記事では、**文字列 / 数値 / 配列 / ハッシュ(連想配列) / Range / 任意のオブジェクト**に対して使えるループ構文やイテレータ、そして制御構文を一挙にまとめました。  
さらに、**実務での具体例**を交えつつ、「どんな場面で使うと良いのか」も紹介していきます。

実務で見返せるようにしていただくととても便利だと思います！

初心者の方はもちろん、実務をある程度行っている方でも
案外知らないメソッドがあるかもしれません。

また、初心者の方向けに、よく使うものや特に理解しておいて欲しいものには
"⭐︎" をつけておくので必ずチェックしてください！

# 1. 文字列(String)のループ
## 1-1. `each_char`
文字列を1文字ずつ取り出します。
~~~ ruby
"Hello".each_char do |ch|
    puts ch
end
# => "H", "e", "l", "l", "o"
~~~

### 使いどころ（実務での具体例）
1. **入力バリデーション**: 1文字ずつ適切に判定したい
2. **暗号化/復号処理**: 1文字ごとにASCIIコード変換などを行いたい
3. **UIの文字アニメーション**: 一文字ずつ表示するエフェクトを実装

---

## 1-2. `each_line`
改行区切りで1行ずつ取得します。
~~~ ruby
multi_lines = "Hello\nWorld\nRuby"
multi_lines.each_line do |line|
  puts line
end
# => "Hello", "World", "Ruby"
(改行(\n)は消えません。)
~~~

### 使いどころ（実務での具体例）
1. **ログファイルの解析**: 1行ごとに読み込み、エラー抽出などを行う  
2. **設定ファイルの読み込み**: 行単位で設定を解析・適用  
3. **テキストインポート**: CSVなどを行単位で処理する

---

## 1-3. `each_byte`
文字列の**バイト値**を順番に取り出します。
~~~ ruby
"ABC".each_byte do |b|
  puts b
end
# => 65, 66, 67 (ASCIIコード)
~~~

### 使いどころ（実務での具体例）
1. **バイナリ解析**: 画像やファイルのバイナリデータを1バイトずつ処理  
2. **プロトコル通信**: TCP/UDPレベルで独自のデータを扱う場合  
3. **暗号化ロジック**: バイト単位でXORなどを行う

---

## 1-4. `each_codepoint`
文字コードポイント（Unicode）を取り出します。

~~~ ruby
"あいう".each_codepoint do |cp|
  puts cp
end
# => 12354, 12356, 12358
~~~

### 使いどころ（実務での具体例）  
1. **多言語対応**: マルチバイト文字（日本語など）を正しく扱いたい時  
2. **文字変換・正規化**: 濁点や半角全角などの調整  
3. **絵文字など特殊文字の処理**: 通常のバイト操作では崩れる可能性がある文字も安全に扱う

---

## 1-5. `scan`
正規表現にマッチする部分を抽出してブロックに渡します。
~~~ ruby
"abc123def456".scan(/\d+/) do |match|
  puts match
end
# => "123", "456"
~~~

### 使いどころ（実務での具体例） 
1. **テキストから数値抽出**: 書類番号や顧客IDを文字列から拾う  
2. **HTMLスクレイピング**: タグや属性を正規表現で解析  
3. **ログやメッセージ解析**: 特定のパターンをマッチしてアラート検知

---

# 2. 数値(Integer)のループ

## 2-1. `times` ⭐︎
指定回数繰り返す。`0`からカウントアップ。
~~~ ruby
3.times do |i|
  puts i
end
# => 0, 1, 2
~~~

### 使いどころ（実務での具体例） 
1. **複数レコード作成**: ダミーデータを指定数だけ生成するとき  
2. **リトライ処理**: 一定回数繰り返すロジック（例: APIリトライ）  
3. **シンプルな繰り返し**: 「○回だけ同じ処理」など

---

## 2-2. `upto`
数値を小さい方から大きい方へカウントアップしながら処理。
~~~ ruby
1.upto(3) do |num|
  puts num
end
# => 1, 2, 3
~~~

### 使いどころ（実務での具体例）  
1. **ページ送り処理**: 1ページ目からNページ目まで順に処理  
2. **ファイル命名**: ファイル名に連番を付ける際のカウントアップ  
3. **IDの自動発行**: 最初から最後まで順にIDを割り振る

---

## 2-3. `downto`
`upto`の逆でカウントダウンします。
~~~ ruby
3.downto(1) do |num|
  puts num
end
# => 3, 2, 1
~~~

### 使いどころ（実務での具体例）  
1. **タイマーのカウントダウン**: 残り時間を計測  
2. **リソース削減**: 高値から順にチェックして途中で打ち切る場合  
3. **逆順表示**: データを後ろから順に並べたいとき

---

## 2-4. `step`
増分（ステップ）を指定してカウントアップ/ダウン。
~~~ ruby
# 1から10まで2刻み
1.step(10, 2) do |n|
  puts n
end
# => 1, 3, 5, 7, 9
~~~

### 使いどころ（実務での具体例） 
1. **サンプリング**: 大量データの中から一定間隔で抽出  
2. **グラフ描画用**: X軸やY軸の目盛を指定間隔で生成  
3. **ループ負荷軽減**: 全要素でなくステップ飛ばしで処理するとき

---

# 3. 配列(Array)のループ
Rubyの配列は`Enumerable`モジュールをincludeしているため、下記の**多くのメソッド**が利用可能です。

## 3-1. `each` ⭐︎
要素を順番に取り出す。
~~~ ruby
[1,2,3].each do |num|
  puts num
end
# => 1, 2, 3
~~~

### 使いどころ（実務での具体例） 
1. **ユーザーリストの処理**: 配列化したユーザーIDをループして処理  
2. **DBテーブル行取得**: 取得したレコードを1行ずつ処理  
3. **一括メール送信**: 宛先リストをループしてメール送信

---

## 3-2. `each_with_index` ⭐︎
要素とインデックスを同時に取得。
~~~ ruby
["Ruby", "Python", "Go"].each_with_index do |lang, i|
  puts "#{i}: #{lang}"
end
# => 0: Ruby
#    1: Python
#    2: Go
~~~

### 使いどころ（実務での具体例）
1. **表示ランキング**: インデックスを順位として表示  
2. **リスト選択UI**: インデックスを選択番号として扱う  
3. **CSVのカラム出力**: ヘッダと列番号を合わせる

---

## 3-3. `map` / `collect` ⭐︎
ブロックの戻り値を**新しい配列**として返す。
~~~ ruby
nums = [1, 2, 3]
squares = nums.map { |n| n * n }
# => [1, 4, 9]
~~~

### 使いどころ（実務での具体例）
1. **型変換・フォーマット変換**: 数字を文字列にするなど  
2. **計算処理**: 数値のリストを一括で平方や割引価格に変換  
3. **APIレスポンス整形**: JSONで受け取った配列要素を加工して返す

---

## 3-4. `select` / `reject` ⭐︎
- `select`: 条件が真の要素を抽出  
- `reject`: 条件が真の要素を除外
~~~ ruby
nums = [1,2,3,4,5,6]
even = nums.select { |n| n.even? }  # => [2,4,6]
odd  = nums.reject { |n| n.even? }  # => [1,3,5]
~~~

### 使いどころ（実務での具体例）
1. **データのフィルタリング**: 年齢20歳以上だけ抽出など  
2. **権限管理**: 管理者アカウントだけ選別、または除外  
3. **稼働状況チェック**: 稼働中のサーバーのみ抽出して監視

---

## 3-5. `find` / `detect` ⭐︎
条件を満たす**最初の要素**を返す。
~~~ ruby
nums = [10, 20, 30, 40]
result = nums.find { |n| n > 25 }
# => 30
~~~

### 使いどころ（実務での具体例）
1. **最初にエラーが出た行を探す**: ログ解析でエラー行を一つだけ特定  
2. **在庫チェック**: 最初に在庫ありの商品を返す  
3. **ユーザー検索**: 複数条件に合うユーザーの中から先頭の1人だけ

---

## 3-6. `find_all` ⭐︎
条件を満たす**すべての要素**を抽出（`select`と同じ動き）。
~~~ ruby
nums = [10, 20, 30, 40]
result = nums.find_all { |n| n > 25 }
# => [30, 40]
~~~

### 使いどころ（実務での具体例） 
1. **複数マッチの検索**: 同じカテゴリーの商品をまとめて抽出  
2. **フィルタリング**: ログファイルから特定のタグ付き行を全取得  
3. **条件付き集計**: ある期間のレコードをすべて取り出して計算

---

## 3-7. `any?` / `all?` / `none?` / `one?`
ブロック条件の一致度合いを**真偽値**で判定。
~~~ ruby
arr = [1, 3, 5]
arr.any? { |n| n.even? }  # => false
arr.all? { |n| n.odd? }   # => true
arr.none? { |n| n.even? } # => true
arr.one? { |n| n == 3 }   # => true
~~~

### 使いどころ（実務での具体例）  
1. **バリデーション**: 値が一つでも不正ならNG, 全部正しければOKなど  
2. **UI警告表示**: 一つでも危険値があれば警告を出す  
3. **リスト状態確認**: 空き枠があるかどうか（any?）、全部使用中か（all?）

---

## 3-8. `partition`
ブロックが真の要素と偽の要素に**2分割**。
~~~ ruby
nums = [1,2,3,4,5,6]
even, odd = nums.partition { |n| n.even? }
# even => [2,4,6]
# odd  => [1,3,5]
~~~

### 使いどころ（実務での具体例）
1. **顧客をVIPと一般に仕分け**: 条件により2つのリストに分けたい  
2. **タグ分け**: タグ付き/タグなしでデータを2分割  
3. **合否判定**: 条件合格/条件不合格を同時に取得

---

## 3-9. `group_by`
ブロックの戻り値をキーにして、要素を**ハッシュ**で返す。
~~~ ruby
words = ["apple", "ant", "banana", "cat"]
grouped = words.group_by { |w| w[0] }
# => {"a"=>["apple","ant"], "b"=>["banana"], "c"=>["cat"]}
~~~

### 使いどころ（実務での具体例）
1. **グループ分け表示**: イニシャルごとにユーザーを分類  
2. **カテゴリ分け集計**: 収支をカテゴリ別にグループ化  
3. **サマリーレポート**: 1日のログを時間帯ごとに分類

---

## 3-10. `inject` / `reduce`
要素を畳み込み、ひとつの値に集約。
~~~ ruby
nums = [1,2,3,4]
sum = nums.inject(0) { |acc, n| acc + n }
# => 10
~~~

### 使いどころ（実務での具体例）
1. **集計処理**: 合計金額や合算ポイントなどを算出  
2. **ハッシュ生成**: 配列からキーや値を加工してハッシュ化  
3. **カスタムロジック**: XORや論理積など、特殊な積算処理

---

## 3-11. `each_with_object`
ブロックに渡されたオブジェクトを加工しつつ、最終的に返す。
~~~ ruby
arr = ["apple", "banana", "cat"]
# 文字と文字数のハッシュを作る
result = arr.each_with_object({}) do |item, hash|
  hash[item] = item.size
end
# => {"apple"=>5, "banana"=>6, "cat"=>3}
~~~

### 使いどころ（実務での具体例） 
1. **辞書（ハッシュ）作成**: 配列の値をキーにしてサイズや属性を保存  
2. **複雑な統計情報**: ブロック内で集計しながらハッシュに格納  
3. **グループ別配列作成**: ループしながらカテゴリごとの配列をつくる

---

## 3-12. `chunk` / `chunk_while`
- `chunk`: ブロックの戻り値が変わったタイミングで配列を区切る  
- `chunk_while`: ブロックが真の間、要素をまとめ続ける
~~~ ruby
nums = [1,1,2,2,2,3,1]
chunks = nums.chunk { |n| n }.to_a
# => [[1,[1,1]],[2,[2,2,2]],[3,[3]],[1,[1]]]

nums2 = [1,2,3,2,3,4,5]
chunked = nums2.chunk_while { |a,b| b > a }
chunked.each { |c| p c }
# => [1,2,3]
#    [2,3,4,5]
~~~

### 使いどころ（実務での具体例）
1. **状態変化の区切り**: ステータスコードが変わる瞬間でグループ化  
2. **連続値のまとまり**: 同じ数字や連続した数字をひとまとめにする  
3. **ログ解析**: エラーコードが続く区間などをまとめて分析

---

## 3-13. `slice_when` / `slice_before` / `slice_after`
複雑な条件で配列を分割する。
~~~ ruby
arr = [1,2,3,10,11,12,20]
sliced = arr.slice_when { |prev, curr| (curr - prev) >= 5 }
sliced.each { |sub| p sub }
# => [1,2,3]
#    [10,11,12]
#    [20]
~~~

### 使いどころ（実務での具体例）
1. **不連続データの仕分け**: 値の差が大きい部分で区切る  
2. **区切り文字を目印に**: 「;」や「:」が出現したらスライスを分ける  
3. **バッチ処理**: 入庫日が変わったらスライスするなどの日付操作

---

## 3-14. `each_slice(n)` / `each_cons(n)`
- `each_slice(n)`: 要素をn個ずつ塊にして取り出す  
- `each_cons(n)`: 要素をn個ずつ1つずつずらして取り出す
~~~ ruby
arr = [1,2,3,4,5,6]
arr.each_slice(2) { |slice| p slice }
# => [1,2], [3,4], [5,6]

arr.each_cons(2) { |cons| p cons }
# => [1,2], [2,3], [3,4], [4,5], [5,6]
~~~

### 使いどころ（実務での具体例）  
1. **大規模処理の分割**: 数千件のデータをまとめてn件ずつ処理  
2. **ペア比較**: 連続する2要素を比較して差分を取るなど  
3. **ログをブロック単位で見る**: 5行ずつまとめて解析

---

## 3-15. `reverse_each`
配列を**末尾から先頭に向かって**要素を取り出す。
~~~ ruby
arr = [1,2,3,4]
arr.reverse_each do |val|
  puts val
end
# => 4, 3, 2, 1
~~~

### 使いどころ（実務での具体例）
1. **最新データから処理**: ログや履歴を後ろから読む  
2. **スタックのような扱い**: 最後に入れた要素から取り出したい  
3. **逆順アルゴリズム**: 昇順で処理済みの場合などに逆順で再チェック

---

# 4. ハッシュ(Hash)のループ
Rubyの`Hash`も`Enumerable`をincludeしているため、`each`, `map`, `select`などほぼすべてのイテレータが利用可能。  
加えて、**キーと値**に特化したイテレータがあります。

## 4-1. `each` ⭐︎
キーと値を順番に取得。
~~~ ruby
person = { name: "Alice", age: 20 }
person.each do |k, v|
  puts "#{k}: #{v}"
end
# => name: Alice
#    age: 20
~~~

### 使いどころ（実務での具体例）
1. **設定値のループ**: 設定キーを読み込んで実行時に適用  
2. **DBカラム名と値のペア処理**: レコードをハッシュ化して保存  
3. **JSONレスポンス解析**: キーと値をひとつずつチェック

---

## 4-2. `each_key`, `each_value`, `each_pair`
~~~ ruby
h = { a: 1, b: 2, c: 3 }

h.each_key { |k| puts k }   # => :a, :b, :c
h.each_value { |v| puts v } # => 1, 2, 3
h.each_pair { |k,v| puts "#{k}-#{v}" }
# => a-1, b-2, c-3
~~~

### 使いどころ（実務での具体例） 
1. **キー一覧だけ表示**: 翻訳辞書などで、存在するキーを確認  
2. **値だけ集計**: ageの平均など値だけを計算  
3. **キー-値セット操作**: 既存のHashを別のHashにコピー・変換

---

## 4-3. `transform_keys`, `transform_values`
ハッシュのキーや値を一括変換して新しいハッシュを返す。
~~~ ruby
h = { name: "bob", city: "Tokyo" }

new_h = h.transform_keys { |key| key.upcase }
# => {"NAME"=>"bob", "CITY"=>"Tokyo"}

new_h2 = h.transform_values { |val| val.upcase }
# => {:name=>"BOB", :city=>"TOKYO"}
~~~

### 使いどころ（実務での具体例） 
1. **キーのフォーマット統一**: APIで受け取ったキーをスネークケースに揃えるなど  
2. **値の暗号化/マスク**: パスワードや秘匿情報を一括で変換  
3. **キー・値の正規化**: 全部小文字・全部大文字などで検索しやすくする

---

# 5. Range オブジェクトのループ
`Range`オブジェクト(`1..5`など)も`Enumerable`をincludeしているので、`each`や`map`などが利用可能です。
~~~ ruby
(1..5).each do |num|
  puts num
end
# => 1, 2, 3, 4, 5

(1..10).step(2) do |n|
  puts n
end
# => 1, 3, 5, 7, 9
~~~

### 使いどころ（実務での具体例）
1. **ページング処理**: 1ページ目からnページ目までを順番に取得  
2. **データ検証**: 数字や文字の連続範囲を一括チェック  
3. **シーケンス生成**: 連番や文字列（"a".."z"）を自動生成

---

# 6. 制御構文 (言語仕様)

## 6-1. `while / until` ⭐︎
~~~ ruby
i = 0
while i < 3
  puts i
  i += 1
end
# => 0,1,2

j = 3
until j < 0
  puts j
  j -= 1
end
# => 3,2,1,0
~~~

### 使いどころ（実務での具体例）
1. **リアルタイム監視**: ある条件が変わるまでループを続ける  
2. **待機処理**: ユーザー入力待ちや外部APIの完了待ち  
3. **状態が変わるまで回す**: フラグが立つまで継続処理

---

## 6-2. `for` ⭐︎
~~~ ruby
for n in [10, 20, 30]
  puts n
end
# => 10,20,30
# (※ Rubyの`for`は内部的に`each`を呼んでいる)
~~~

### 使いどころ（実務での具体例） 
1. **他言語出身者向け**: `for`に慣れている人が書きやすい  
2. **簡易スクリプト**: 小規模のスクリプトで短く書きたいとき  
3. **範囲を明示**: `for i in 1..n` でループ範囲が分かりやすい

---

## 6-3. `loop do ... end` ⭐︎
~~~ ruby
count = 0
loop do
  puts count
  count += 1
  break if count > 2
end
# => 0, 1, 2
~~~

### 使いどころ（実務での具体例）
1. **無限ループが基本**: サーバーのメインループなど、breakを入れるまで継続  
2. **カスタム制御**: 条件が複雑な抜け方をするループ  
3. **イベント待ち**: 特定のイベントが来るまで永久に回し続ける

---

## 6-4. `begin ... end while/until` ⭐︎
~~~ ruby
k = 0
begin
  puts k
  k += 1
end while k < 3
# => 0,1,2
~~~

### 使いどころ（実務での具体例）
1. **最低1回実行必須**: パスワード入力など、最初の1回は必ず表示  
2. **ユーザー選択リピート**: 一度操作してから、継続するか選ばせる  
3. **条件があとで決まる**: 実行後に状態をチェックしたい処理

---

# 最後に
ここではRubyのループ処理を**幅広く網羅**してみました。
実際に実務ではあまり使わないものもあるので、実際に特殊な処理をしたいときなどに「こんなものもあったな...」と思い出せるくらいに眺めておくと良いかもしれません。

実務の具体例も参考に、ぜひ「状況に合ったループ処理」を使いこなして、読みやすくて保守しやすいコードを書いてみてください。