Ruby 2.1.0 リファレンスマニュアル > ライブラリ一覧 > 組み込みライブラリ > Enumerator::Lazyクラス
クラスの継承リスト: Enumerator::Lazy < Enumerator < Enumerable < Object < Kernel < BasicObject
map や select などのメソッドの遅延評価版を提供するためのクラス。
動作は通常の Enumerator と同じですが、以下のメソッドが遅延評価を行う (つまり、配列ではなく Enumerator を返す) ように再定義されています。
Lazyオブジェクトは、Enumerable#lazyメソッドによって生成されます。
Lazyから値を取り出すには、Enumerator::Lazy#force または Enumerable#first を呼びます。
例:
# 二乗して偶数になるような整数を、小さい方から5個表示する p (1..Float::INFINITY).lazy.select{|n| (n**2).even?}.first(5) # LTSV (http://ltsv.org/) 形式のログファイルから検索を行う # Enumerator::Lazy#map は配列ではなく Enumerator を返すため、 # 巨大な配列を確保しようとしてメモリを使い切ったりはしない open("log.txt"){|f| f.each_line.lazy.map{|line| Hash[line.split(/\t/).map{|s| s.split(/:/, 2)}] }.select{|hash| hash["req"] =~ /GET/ && hash["status"] == "200" }.each{|hash| p hash } }
new(obj, size=nil) {|yielder, *values| ... } -> Enumerator::Lazy
[permalink][rdoc]Lazy Enumerator を作成します。Enumerator::Lazy#force メソッドなどに よって列挙が実行されたとき、objのeachメソッドが実行され、値が一つずつ ブロックに渡されます。ブロックは、yielder を使って最終的に yield される値を 指定できます。
Enumerable#filter_map と、その遅延評価版を定義する例:
module Enumerable def filter_map(&block) map(&block).compact end end class Enumerator::Lazy def filter_map Lazy.new(self) do |yielder, *values| result = yield *values yielder << result if result end end end (1..Float::INFINITY).lazy.filter_map{|i| i*i if i.even?}.first(5) # => [4, 16, 36, 64, 100]
[SEE_ALSO] Enumerator.new
chunk {|elt| ... } -> Enumerator::Lazy
[permalink][rdoc]chunk(initial_state) {|elt, state| ... } -> Enumerator::Lazy
Enumerable#chunk と同じですが、配列ではなく Enumerator::Lazy を返します。
[SEE_ALSO] Enumerable#chunk
map {|item| ... } -> Enumerator::Lazy
[permalink][rdoc]collect {|item| ... } -> Enumerator::Lazy
Enumerable#map と同じですが、配列ではなくEnumerator::Lazy を返します。
[SEE_ALSO] Enumerable#map
flat_map {|item| ... } -> Enumerator::Lazy
[permalink][rdoc]collect_concat {|item| ... } -> Enumerator::Lazy
ブロックの実行結果をひとつに繋げたものに対してイテレートするような Enumerator::Lazy のインスタンスを返します。
["foo", "bar"].lazy.flat_map {|i| i.each_char.lazy}.force #=> ["f", "o", "o", "b", "a", "r"]
ブロックの返した値 x は、以下の場合にのみ分解され、連結されます。
それ以外のときは、x は分解されず、そのままの値として使われます。
[{a:1}, {b:2}].lazy.flat_map {|i| i}.force #=> [{:a=>1}, {:b=>2}]
[SEE_ALSO] Enumerable#flat_map
drop(n) -> Enumerator::Lazy
[permalink][rdoc]Enumerable#drop と同じですが、配列ではなくEnumerator::Lazy を返します。
[SEE_ALSO] Enumerable#drop
drop_while -> Enumerator::Lazy
[permalink][rdoc]drop_while {|item| ... } -> Enumerator::Lazy
Enumerable#drop_while と同じですが、配列ではなくEnumerator::Lazy を返します。
[SEE_ALSO] Enumerable#drop_while
to_enum(method = :each, *args) -> Enumerator::Lazy
[permalink][rdoc]enum_for(method = :each, *args) -> Enumerator::Lazy
to_enum(method = :each, *args) {|*args| block} -> Enumerator::Lazy
enum_for(method = :each, *args) {|*args| block} -> Enumerator::Lazy
Object#to_enum と同じですが、Enumerator::Lazy を返します。
to_enum は「ブロック付きで呼ぶとループを実行し、ブロックを省略した場合は Enumerator を返す」ようなメソッドを定義するときによく使われます。 このときに lazy 性が正しく引き継がれるように、Lazy#to_enum は 素のEnumerator ではなく Enumerator::Lazy を返すようになっています。
例:
module Enumerable # 要素をn回ずつ繰り返すメソッド # 例:[1,2,3].repeat(2) #=> [1,1,2,2,3,3] def repeat(n) raise ArgumentError if n < 0 if block_given? each do |*val| n.times { yield *val } end else to_enum(:repeat, n) end end end r = 1..10 p r.map{|n| n**2}.repeat(2).first(5) #=> [1, 1, 4, 4, 9] r = 1..Float::INFINITY p r.lazy.map{|n| n**2}.repeat(2).first(5) #=> [1, 1, 4, 4, 9] # Lazy#to_enum のおかげで、repeat の返り値は # もとが Enumerator のときは Enumerator に、 # もとが Lazy のときは Lazy になる
select {|item| ... } -> Enumerator::Lazy
[permalink][rdoc]find_all {|item| ... } -> Enumerator::Lazy
Enumerable#select と同じですが、配列ではなくEnumerator::Lazy を返します。
[SEE_ALSO] Enumerable#select
force(*args) -> [object]
[permalink][rdoc]全ての要素を含む配列を返します。Lazy から実際に値を取り出すのに使います。
Enumerable#to_a のエイリアスです。
grep(pattern) {|item| ... } -> Enumerator::Lazy
[permalink][rdoc]Enumerable#grep と同じですが、配列ではなくEnumerator::Lazy を返します。
[SEE_ALSO] Enumerable#grep
lazy -> self
[permalink][rdoc]self を返します。
reject {|item| ... } -> Enumerator::Lazy
[permalink][rdoc]Enumerable#reject と同じですが、配列ではなくEnumerator::Lazy を返します。
[SEE_ALSO] Enumerable#reject
slice_before(pattern) -> Enumerator::Lazy
[permalink][rdoc]slice_before {|elt| bool } -> Enumerator::Lazy
slice_before(initial_state) {|elt, state| bool } -> Enumerator::Lazy
Enumerable#slice_before と同じですが、配列ではなく Enumerator::Lazy を返します。
[SEE_ALSO] Enumerable#slice_before
take(n) -> Enumerator::Lazy
[permalink][rdoc]Enumerable#take と同じですが、配列ではなくEnumerator::Lazy を返します。
n が大きな数 (100000とか) の場合に備えて再定義されています。 配列が必要な場合は Enumerable#first を使って下さい。
[SEE_ALSO] Enumerable#take
take_while -> Enumerator::Lazy
[permalink][rdoc]take_while {|item| ... } -> Enumerator::Lazy
Enumerable#take_while と同じですが、配列ではなくEnumerator::Lazy を返します。
[SEE_ALSO] Enumerable#take_while
zip(*lists) -> Enumerator::Lazy
[permalink][rdoc]zip(*lists) {|v1, v2, ...| ... } -> nil
Enumerable#zip と同じですが、配列ではなくEnumerator::Lazy を返します。
ただし一貫性のため、ブロック付きで呼び出した場合は Enumerable#zip と 同じ挙動になります。
[SEE_ALSO] Enumerable#zip