LoginSignup
0
0

More than 1 year has passed since last update.

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

Posted at

繰り返し処理(ループ)とは

  • 繰り返し処理とは、決まった回数や条件を満たしているは同じ処理を繰り返し行う場合に使います。
  • Rubyの繰り返し処理は配列やハッシュのメソッドなどの、制御構造内での繰り返し処理や、ブロック付きメソッド呼び出しという制御構造を定義する事ができるものまで多くの種類があります。
  • 今回はその中でよく使う4つを簡略的に紹介します。

eachメソッド

eachメソッドはRubyにおいて非常にメジャーな繰り返し処理の1つであり、配列やハッシュなどのコレクションオブジェクトを操作する際によく使われます。

  • eachメソッド 構文
    collection.each do |変数|
      # 処理
    end
    
    ここでのcollectionは繰り返し処理を行う対象となるオブジェクトで、変数はブロック内のdo ~ endで各要素を受け取るための変数名です。
    • 配列を対象としたeachの例
      fruits = ["apple", "banana", "orange"]
      fruits.each do |fruit|
        puts fruit
      end
      
      このコードではfruits配列の各要素をfruitという変数に代入して、putsメソッドで出力しています。
      出力
      apple
      banana
      orange
      

each_with_indexメソッド

  • eachメソッドの派生でeach_with_indexメソッドというのがあります。
    eachメソッドと同様に繰り返しの処理を行いつつ、各要素のインデックスも同時に受け取ることができます。
    each_with_index
    collection.each_with_index do |item, index|
        # ブロックでの処理
    end
    
    collectionに繰り返し処理を行いたい配列やハッシュなどを指定し、ブロック内でのitemには配列の要素やハッシュの値、indexには配列のインデックスやハッシュのキーが渡されます。
    each_with_index
    fruits = ['apple', 'banana', 'orange']
    fruits.each_with_index do |fruit, i|
      puts "#{i}: #{fruit}"
    end
    
    このコードを実行すると以下の様に出力されるが、インデックス番号は0から始まっている。
    出力
    0: apple
    1: banana
    2: orange
    
    この番号をeach_with_indexメソッドの第2引数に、インデックス番号の開始値を指定することで番号を任意の位置から始める事ができます。
    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メソッド 構文

    times構文
    回数.times do |変数|
    # 繰り返したい処理
    end
    #または
    回数.times { |変数|
    # 繰り返したい処理
    }
    

    回数には繰り返し回数を指定し、ブロック内の処理が指定した回数文繰り返されます。ブロック内には繰り返し処理で使用するための変数を定義する事ができます。
    変数の部分は省略可能で、以下の様に簡略化して書くこともできます。

    3.times do
      puts "Hello, world!"
    end
    #=> Hello, world!
    #=> Hello, world!
    #=> Hello, world!
    

    ただし、timesメソッドのブロック変数には繰り返し処理が現在何回目であるかを示す数値が自動的に格納されます。

    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メソッド 構文

    map 構文
    array.map { |item| block }
    

    上記のarrayは変換したい配列を指定しています。
    itemは配列の各要素がブロックに渡される際の引数で、blockは配列の各要素に対して実行されるブロックです。
    mapメソッドはブロックの戻り値を新しい配列の要素として格納してその配列を返します。

    mapメソッドの例
    arr = [1, 2, 3, 4, 5]
    new_arr = arr.map { |n| n * 2 }
    puts new_arr # => [2, 4, 6, 8, 10]
    

    上記の例ではarrという配列の各要素に対して2倍した新しい配列を作成している。mapメソッド内のn * 2によって各要素を2倍して、新しい配列であるnew_arrに代入している。

    mapメソッドは他のメソッドと組み合わせて使用することができて便利です。
    後述するselectメソッドとの併用もでき、mapメソッドで配列の要素を変更した新しい配列を作成したあと、selectメソッドを使って条件に一致する要素だけを抽出する事もできます。

    • mapselectを組み合わせて、配列から条件に合う要素だけを抜き出す。
      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]
      
    • mapreduceを組み合わせて、配列の各要素を処理し、その結果を合算する。
      numbers = [1, 2, 3, 4, 5]
      sum_of_squares = numbers.map { |n| n**2 }.reduce(0) { |sum, n| sum+ n } 
      # => 55
      
    • mapwith_indexを組み合わせて、配列の各要素に対して、そのインデックス番号も一緒に扱う。
      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文 構文
    while 構文
    while 条件式 do
      # 繰り返したい処理
    end
    
    while文は条件を満たしている限り何度も同じ処理を繰り返すので、データの処理をすべてのデータが処理されるまで繰り返したい場合などに使えます。
    i = 1
    while i <= 10 do
      puts i
      i += 1
    end
    
    上記の例では、変数iが1から10になるまで繰り返し処理を行っています。
    iが10になると条件式のi <= 10falseとなるので、while文を抜けて次の処理に進みます。
    出力
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
  • while文ではループを行う際に、条件式が常にtrueにならないようにループ内で条件式が変更されるようにする必要があります。
    そうでないと、無限ループに陥り条件を抜け出せなくなる可能性があります。
  • while文の条件式は、比較演算子などを用いて真偽値を返すようにします。
  • 以上の点を踏まえてwhile文を使用する際は条件式がどのようなときにループを終了するか、あらかじめ明確に決めておく必要があります。

まとめ

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

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

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

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

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

0
0
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
0
0