Ruby

【Ruby】インデックス有りのループ処理を行う場合、each_with_indexよりもwith_indexの方が便利だった

Ruby

 

インデックス付きでループ処理を行いたい場合、これまではeach_with_indexを使ってきました。しかしそれよりも便利なwith_indexというメソッドを知る機会があったので、今回はそのメソッドについて簡単に紹介したいと思います。

each_with_index

インデックス番号を割り振りながらループ処理を行うことができるメソッドで有名なのがeach_with_indexです。

fruits = ["apple", "banana", "kiwi"]

fruits.each_with_index do | fruit, index |
  puts "#{index}番目のフルーツは#{fruit}です"
end

=> 0番目のフルーツはappleです。
=> 1番目のフルーツはbananaです。
=> 2番目のフルーツはkiwiです。

 

しかしeach_with_indexは0番目から始まってしまうため、1番目から指定したい場合は以下のように明示的に+1する必要があります。

fruits = ["apple", "banana", "kiwi"]

fruits.each_with_index do | fruit, index |
  puts "#{index + 1}番目のフルーツは#{fruit}です"
end

=> 1番目のフルーツはappleです。
=> 2番目のフルーツはbananaです。
=> 3番目のフルーツはkiwiです。

 

この面倒な処理をしなくて良いのがwith_indexメソッドになります。

with_index

with_indexはインデックスの最初の値を指定することができるメソッドです。with_index(1)とすることでインデックスを1から、with_index(2)とすることでインデックスを2から始めることができます。

fruits = ["apple", "banana", "kiwi"]

fruits.each.with_index(1) do | fruit, index |
  puts "#{index}番目のフルーツは#{fruit}です"
end

=> 1番目のフルーツはappleです。
=> 2番目のフルーツはbananaです。
=> 3番目のフルーツはkiwiです。
fruits = ["apple", "banana", "kiwi"]

fruits.each.with_index(2) do | fruit, index |
  puts "#{index}番目のフルーツは#{fruit}です"
end

=> 2番目のフルーツはappleです。
=> 3番目のフルーツはbananaです。
=> 4番目のフルーツはkiwiです。

 

with_indexメソッドはEnumeratorクラスのメソッドのため、eachだけでなくmap(map.with_index(1))やselect(select.with_index(1))といったEnumerableモジュールにも使用することができます。

module Enumerable

繰り返しを行なうクラスのための Mix-in。このモジュールのメソッドは全て each を用いて定義されているので、インクルードするクラスには each が定義されていなければなりません。

Array, Hash, Range, Enumerator等のクラスで、 Enumerableモジュールはインクルードされています。ただし、効率化のため、そのクラスでEnumerableと同名・同等の機能を再定義(オーバーライド)しているケースも少なくなく、特にArrayクラスでは同名のメソッドを再定義していることが多いです。

参照: module Enumerable

まとめ

  • each_with_indexはインデックス番号を割り振りながらループ処理を行うことができるメソッド
  • each_with_indexはインデックスが0から始まる
  • with_indexはインデックスの最初の値を指定することができるメソッド
  • with_indexメソッドはEnumeratorクラスのメソッドのため、Enumerableモジュールにも使用することができる

参考

 

 

今回はインデックス番号を指定しながらループ処理を行うことができるメソッド、with_indexについて紹介しました。Railsにはまだまだ知らない便利なメソッドや機能があるものですね。