0Pricing
Ruby Academy · レッスン

Enumerable のインクルード

map/select をすぐに使えるようにします。

「Enumerable のインクルード」はCoddyKit上の無料Ruby Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはRuby Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Ruby Academyコースには全4レッスンが含まれています。

map と select を無料で利用する

クラスにeachがあれば、Enumerableをミックスインするだけで、map、select、reduce、sort、min、maxなど、独自のeachを基盤とする多くのメソッドをすぐに利用できます。

class Bag
  include Enumerable
  def initialize(*x); @x = x; end
  def each; @x.each { |i| yield i }; end
end
p Bag.new(1, 2, 3).map { |n| n * 10 }

契約

仕組みは簡単です。Enumerableをインクルードし、eachを定義します。Enumerableは内部で独自のeachを呼び出し、それを基盤として他のすべての機能を動かします。

class Squares
  include Enumerable
  def initialize(n); @n = n; end
  def each
    (1..@n).each { |i| yield i * i }
  end
end
p Squares.new(5).to_a

select でフィルタリングする

selectは、ブロックが真と評価された要素を残します。rejectはその逆です。

class Nums
  include Enumerable
  def initialize(*x); @x = x; end
  def each; @x.each { |i| yield i }; end
end
n = Nums.new(1, 2, 3, 4, 5, 6)
p n.select(&:even?)
p n.reject(&:even?)

reduce で集計する

reduceはコレクションを1つの値に畳み込みます。

class Cart
  include Enumerable
  def initialize(*p); @p = p; end
  def each; @p.each { |i| yield i }; end
end
puts Cart.new(5, 10, 15).reduce(:+)

min、max、sort

要素が比較可能であれば、比較に基づくメソッドを利用できます。

class Scores
  include Enumerable
  def initialize(*n); @n = n; end
  def each; @n.each { |i| yield i }; end
end
s = Scores.new(7, 2, 9, 4)
puts s.min
puts s.max
p s.sort

find と include?

findは条件に一致する最初の要素を返し、include?は要素が含まれているかを確認します。

class Words
  include Enumerable
  def initialize(*w); @w = w; end
  def each; @w.each { |x| yield x }; end
end
w = Words.new("cat", "dog", "bird")
puts w.find { |x| x.length == 4 }
puts w.include?("dog")

group_by と partition

Enumerableには、強力なグループ化用のヘルパーが用意されています。

class Nums
  include Enumerable
  def initialize(*x); @x = x; end
  def each; @x.each { |i| yield i }; end
end
n = Nums.new(1, 2, 3, 4, 5)
p n.group_by(&:even?)
p n.partition(&:odd?)

ソートには Comparable な要素が必要

要素が独自のオブジェクトの場合は、<=>(Comparable 経由)を与えて、sort、min、maxが要素の順序を判断できるようにします。

Item = Struct.new(:price) do
  include Comparable
  def <=>(o); price <=> o.price; end
end
class Shelf
  include Enumerable
  def initialize(*i); @i = i; end
  def each; @i.each { |x| yield x }; end
end
shelf = Shelf.new(Item.new(30), Item.new(10), Item.new(20))
p shelf.min.price

each_with_index

Enumerableには、より柔軟な反復処理のためのeach_with_indexとeach_with_objectも用意されています。

class Letters
  include Enumerable
  def initialize(*l); @l = l; end
  def each; @l.each { |x| yield x }; end
end
Letters.new("a", "b", "c").each_with_index do |letter, i|
  puts "#{i}: #{letter}"
end

メソッドをチェーンする

これらのメソッドは配列または Enumerator を返すため、表現力の高いパイプラインとしてチェーンできます。

class Nums
  include Enumerable
  def initialize(*x); @x = x; end
  def each; @x.each { |i| yield i }; end
end
result = Nums.new(1, 2, 3, 4, 5, 6).select(&:even?).map { |n| n * n }
p result

まとめ

Enumerableをインクルードすると、大きなメリットがあります。

  • eachを1回定義するだけで済みます。
  • map、select、reduce、sort、find、group_byなど、数十種類以上のメソッドを利用できます。
  • 要素に Comparable を追加すると、順序を扱うメソッドを利用できます。
class Range5
  include Enumerable
  def each; (1..5).each { |n| yield n }; end
end
puts Range5.new.sum

確認

Enumerableのインクルードについての理解度を確認しましょう。

振り返り

Enumerableのインクルードについて学びました。

  • eachを定義してモジュールをインクルードすると、機能一式を利用できます。
  • map、select、reduce、find、group_byはすべて独自のeachを基盤として動作します。
  • 要素の順序付けには<=>が必要です。
  • メソッドをチェーンしてパイプラインを構築できます。
class Tens
  include Enumerable
  def each; [10, 20, 30].each { |n| yield n }; end
end
p Tens.new.map { |n| n + 1 }

よくある質問

「Enumerable のインクルード」レッスンは無料ですか?

はい。「Enumerable のインクルード」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Ruby Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Ruby Academyコースには全4レッスンが含まれています。

「Enumerable のインクルード」で何を学びますか?

map/select をすぐに使えるようにします。 ブラウザで直接実行するハンズオンコードでRuby Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Ruby Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのRuby Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。

「Enumerable のインクルード」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このRuby Academyレッスンでコードを書いて実行できますか?

はい。すべてのRuby Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. カスタム each の記述
  2. Enumerable のインクルード
  3. 遅延 Enumerator
  4. Enumerator オブジェクト
← Ruby Academyに戻る