Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

Rubyのmapやselectでもeach_with_indexみたいにindexを使いたいときはEnumerator#with_index

More than 1 year has passed since last update.

Rubyで便利なEnumerable module.

eachが定義されているクラスであればincludeできるこのmoduleですが、Array Hashなどが最初からincludeしており、そのおかげでeach_with_index, min, max, select, map, all?/any?, sort ... などといったrubyでは欠かせないメソッド群が使用できるようになります。

Enumerableなクラスのインスタンス(Enumerator)はEnumerator#with_indexが使える

さて、このように様々なメソッドがあるEnumerableですが、時たま使いたくなるのはeach_with_indexのwith_indexの部分。

要素ごとにリストの中での位置を何らかの方法で取得するのもいいんですが、mapやselectのときでも最初からindex使えるといいのになーと思って調べていたらEnumerator#with_indexなる便利なものがあるやんけ。

[100, 200, 300].map.with_index { |num, index| [num, index] }
#=>  [[100, 0], [200, 1], [300, 2]]

[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144]
  .select.with_index { |num, index|( num % (index + 1)).zero? }
#=> [1, 5, 144]

ここでのミソは、Enumerableのメソッドの内幾つかのメソッドがブロックをとらないときにEnumeratorを返すところであり、以下のメソッド群がそれに当たります。

  • map / colect
  • flat_map / collect_concat
  • cycle
  • find / detect
  • drop_while
  • each_cons
  • each_entry
  • each_slice
  • each_with_index
  • each_with_object
  • find_all / select
  • find_index
  • group_by
  • max_by / min_by / minmax_by
  • partition
  • reject
  • reverse_each
  • slice_before
  • sort_by
  • take_while

これは便利!

参照: Ruby リファレンスマニュアル

http://docs.ruby-lang.org/ja/2.3.0/class/Enumerable.html#I_COLLECT

もう一回丁寧に読む事にする。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away