Примеры использования "ленивых" итераторов (lazy enumerators) в Ruby 2. Итераторы "по требованию".
Enumerable может быть превращен (получен с помощью) в "ленивый" с помощью нового метода Enumerable#lazy:
lines = File.foreach('a_very_large_file')
.lazy # so we only read the necessary parts!
.select {|line| line.length < 10 }
.map(&:chomp)
.each_slice(3)
.map {|lines| lines.join(';').downcase }
.take_while {|line| line.length > 20 }
# => Lazy enumerator, nothing executed yet
lines.first(3) # => Reads the file until it returns 3 elements
# or until an element of length <= 20 is
# returned (because of the take_while)
# To consume the enumerable:
lines.to_a # or...
lines.force # => Reads the file and returns an array
lines.each{|elem| puts elem } # => Reads the file
# and prints the resulting elements
Помните, что lazy будет зачастую более медленным, чем обычная версия итератора (non lazy). Он должен использоваться только тогда, когда это действительно целесообразно, а не только, чтобы избежать создания массива-посредника.
require 'fruity'
r = 1..100
compare do
lazy { r.lazy.map(&:to_s).each_cons(2).map(&:join).to_a }
direct { r.map(&:to_s).each_cons(2).map(&:join) }
end
# => direct is faster than lazy by 2x ± 0.1
Примеры использования "ленивых" итераторов (lazy enumerators) в Ruby 2. Итераторы "по требованию".
Enumerable
может быть превращен (получен с помощью) в "ленивый" с помощью нового методаEnumerable#lazy
:Помните, что lazy будет зачастую более медленным, чем обычная версия итератора (non lazy). Он должен использоваться только тогда, когда это действительно целесообразно, а не только, чтобы избежать создания массива-посредника.