Чтобы увидеть, как lazy
влияет на вычисления, давайте рассмотрим пример. Сначала создайте файл:
str =<<~_
Now is the
time for all
good Ruby coders
to come to
the aid of
their bowling
team
_
fname = 't'
File.write(fname, str)
#=> 82
и укажите размер среза:
slice_size = 4
Теперь я буду читать строки одну за другой, разбивать строки на слова, удалять повторяющиеся слова и затем добавлять эти слова в массив. Как только массив будет содержать как минимум 4 слова, я возьму первые четыре и сопоставлю их с самым длинным словом из 4. Ниже приведен код для этого. Чтобы показать, как продвигаются вычисления, я солю код с операторами puts
. Обратите внимание, что IO::foreach без блок возвращает перечислитель.
IO.foreach(fname).
lazy.
tap { |o| puts "o1 = #{o}" }.
flat_map { |line|
puts "line = #{line}"
puts "line.split.uniq = #{line.split.uniq} "
line.split.uniq }.
tap { |o| puts "o2 = #{o}" }.
each_slice(slice_size).
tap { |o| puts "o3 = #{o}" }.
map { |arr|
puts "arr = #{arr}, arr.max = #{arr.max_by(&:size)}"
arr.max_by(&:size) }.
tap { |o| puts "o3 = #{o}" }.
to_a
#=> ["time", "good", "coders", "bowling", "team"]
Отображается следующее:
o1 = #<Enumerator::Lazy:0x00005992b1ab6970>
o2 = #<Enumerator::Lazy:0x00005992b1ab6880>
o3 = #<Enumerator::Lazy:0x00005992b1ab6678>
o3 = #<Enumerator::Lazy:0x00005992b1ab6420>
line = Now is the
line.split.uniq = ["Now", "is", "the"]
line = time for all
line.split.uniq = ["time", "for", "all"]
arr = ["Now", "is", "the", "time"], arr.max = time
line = good Ruby coders
line.split.uniq = ["good", "Ruby", "coders"]
arr = ["for", "all", "good", "Ruby"], arr.max = good
line = to come to
line.split.uniq = ["to", "come"]
line = the aid of
line.split.uniq = ["the", "aid", "of"]
arr = ["coders", "to", "come", "the"], arr.max = coders
line = their bowling
line.split.uniq = ["their", "bowling"]
arr = ["aid", "of", "their", "bowling"], arr.max = bowling
line = team
line.split.uniq = ["team"]
arr = ["team"], arr.max = team
Если строка lazy.
удалена, возвращаемое значение остается тем же, но отображается следующее (.to_a
в конце теперь лишнее):
o1 = #<Enumerator:0x00005992b1a438f8>
line = Now is the
line.split.uniq = ["Now", "is", "the"]
line = time for all
line.split.uniq = ["time", "for", "all"]
line = good Ruby coders
line.split.uniq = ["good", "Ruby", "coders"]
line = to come to
line.split.uniq = ["to", "come"]
line = the aid of
line.split.uniq = ["the", "aid", "of"]
line = their bowling
line.split.uniq = ["their", "bowling"]
line = team
line.split.uniq = ["team"]
o2 = ["Now", "is", "the", "time", "for", "all", "good", "Ruby",
"coders", "to", "come", "the", "aid", "of", "their",
"bowling", "team"]
o3 = #<Enumerator:0x00005992b1a41a08>
arr = ["Now", "is", "the", "time"], arr.max = time
arr = ["for", "all", "good", "Ruby"], arr.max = good
arr = ["coders", "to", "come", "the"], arr.max = coders
arr = ["aid", "of", "their", "bowling"], arr.max = bowling
arr = ["team"], arr.max = team
o3 = ["time", "good", "coders", "bowling", "team"]
person
Cary Swoveland
schedule
10.01.2020
map
там, где вы имеете в видуeach
. - person Sergio Tulentsev   schedule 10.01.2020FileReader
? В Ruby естьFile.read
, но он не возвращает перечислитель. - person Stefan   schedule 10.01.2020rio
для чтения файла. - person user789   schedule 10.01.20201.upto(3).lazy.flat_map { |i| [i, i] }.each_slice(3).to_a
возвращает[[1, 1, 2], [2, 3, 3]]
, что мне кажется правильным. Может быть, вы слишком упростили свой пример? - person Stefan   schedule 10.01.2020arr
, хотите ли вы читать переменное количество строк файла в цикле, где в каждом цикле строки считываются и элементы добавляются кarr
до тех пор, покаarr
не будет содержать не менее 100 объектов, и в это время первые 100 элементы изarr
удаляются и обрабатываются? Если это так, вы не можете просто связать методы; вам нужно прочитать файл построчно, используя IO::foreach, скажем, а затем выполнить необходимые операции в блокеforeach
. - person Cary Swoveland   schedule 10.01.2020FileReader::read
(что бы это ни было) действительно возвращает перечислитель по строкам, напримерIO::foreach
. - person Sergio Tulentsev   schedule 10.01.2020