19
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

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

Last updated at Posted at 2025-02-10

はじめに

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

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

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

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

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

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

1. 文字列(String)のループ

1-1. each_char

文字列を1文字ずつ取り出します。

"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行ずつ取得します。

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

文字列のバイト値を順番に取り出します。

"ABC".each_byte do |b|
  puts b
end
# => 65, 66, 67 (ASCIIコード)

使いどころ(実務での具体例)

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

1-4. each_codepoint

文字コードポイント(Unicode)を取り出します。

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

使いどころ(実務での具体例)

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

1-5. scan

正規表現にマッチする部分を抽出してブロックに渡します。

"abc123def456".scan(/\d+/) do |match|
  puts match
end
# => "123", "456"

使いどころ(実務での具体例)

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

2. 数値(Integer)のループ

2-1. times ⭐︎

指定回数繰り返す。0からカウントアップ。

3.times do |i|
  puts i
end
# => 0, 1, 2

使いどころ(実務での具体例)

  1. 複数レコード作成: ダミーデータを指定数だけ生成するとき
  2. リトライ処理: 一定回数繰り返すロジック(例: APIリトライ)
  3. シンプルな繰り返し: 「○回だけ同じ処理」など

2-2. upto

数値を小さい方から大きい方へカウントアップしながら処理。

1.upto(3) do |num|
  puts num
end
# => 1, 2, 3

使いどころ(実務での具体例)

  1. ページ送り処理: 1ページ目からNページ目まで順に処理
  2. ファイル命名: ファイル名に連番を付ける際のカウントアップ
  3. IDの自動発行: 最初から最後まで順にIDを割り振る

2-3. downto

uptoの逆でカウントダウンします。

3.downto(1) do |num|
  puts num
end
# => 3, 2, 1

使いどころ(実務での具体例)

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

2-4. step

増分(ステップ)を指定してカウントアップ/ダウン。

# 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 ⭐︎

要素を順番に取り出す。

[1,2,3].each do |num|
  puts num
end
# => 1, 2, 3

使いどころ(実務での具体例)

  1. ユーザーリストの処理: 配列化したユーザーIDをループして処理
  2. DBテーブル行取得: 取得したレコードを1行ずつ処理
  3. 一括メール送信: 宛先リストをループしてメール送信

3-2. each_with_index ⭐︎

要素とインデックスを同時に取得。

["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 ⭐︎

ブロックの戻り値を新しい配列として返す。

nums = [1, 2, 3]
squares = nums.map { |n| n * n }
# => [1, 4, 9]

使いどころ(実務での具体例)

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

3-4. select / reject ⭐︎

  • select: 条件が真の要素を抽出
  • reject: 条件が真の要素を除外
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 ⭐︎

条件を満たす最初の要素を返す。

nums = [10, 20, 30, 40]
result = nums.find { |n| n > 25 }
# => 30

使いどころ(実務での具体例)

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

3-6. find_all ⭐︎

条件を満たすすべての要素を抽出(selectと同じ動き)。

nums = [10, 20, 30, 40]
result = nums.find_all { |n| n > 25 }
# => [30, 40]

使いどころ(実務での具体例)

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

3-7. any? / all? / none? / one?

ブロック条件の一致度合いを真偽値で判定。

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分割

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

ブロックの戻り値をキーにして、要素をハッシュで返す。

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

要素を畳み込み、ひとつの値に集約。

nums = [1,2,3,4]
sum = nums.inject(0) { |acc, n| acc + n }
# => 10

使いどころ(実務での具体例)

  1. 集計処理: 合計金額や合算ポイントなどを算出
  2. ハッシュ生成: 配列からキーや値を加工してハッシュ化
  3. カスタムロジック: XORや論理積など、特殊な積算処理

3-11. each_with_object

ブロックに渡されたオブジェクトを加工しつつ、最終的に返す。

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: ブロックが真の間、要素をまとめ続ける
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

複雑な条件で配列を分割する。

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つずつずらして取り出す
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

配列を末尾から先頭に向かって要素を取り出す。

arr = [1,2,3,4]
arr.reverse_each do |val|
  puts val
end
# => 4, 3, 2, 1

使いどころ(実務での具体例)

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

4. ハッシュ(Hash)のループ

RubyのHashEnumerableをincludeしているため、each, map, selectなどほぼすべてのイテレータが利用可能。
加えて、キーと値に特化したイテレータがあります。

4-1. each ⭐︎

キーと値を順番に取得。

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

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

ハッシュのキーや値を一括変換して新しいハッシュを返す。

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しているので、eachmapなどが利用可能です。

(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 ⭐︎

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 ⭐︎

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 ⭐︎

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 ⭐︎

k = 0
begin
  puts k
  k += 1
end while k < 3
# => 0,1,2

使いどころ(実務での具体例)

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

最後に

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

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

19
18
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?