Ленивые перечислители
Ленивое вычисление
«Ленивые перечислители» — бесплатный урок Ruby Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Ruby Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Ruby Academy содержит 4 уроков всего.
Ленивое вычисление
Обычно методы Enumerable обрабатывают всю коллекцию сразу. Ленивый перечислитель обрабатывает элементы по одному и только по мере необходимости. Это позволяет работать с огромными и даже бесконечными последовательностями.
result = (1..Float::INFINITY).lazy.map { |n| n * 2 }.first(5)
p resultПроблема обычных методов
Вызов map для бесконечного диапазона без lazy никогда не завершится, поскольку сначала пытается построить полный результирующий массив.
# Eager version would hang. Lazy completes instantly:
first_three = (1..Float::INFINITY).lazy.select(&:even?).first(3)
p first_threeСоздание ленивого перечислителя
Вызовите .lazy для любого перечисляемого объекта, чтобы получить его ленивую версию. Методы в цепочке после этого также становятся ленивыми.
lazy = (1..10).lazy
puts lazy.classНичего не выполняется до принудительного запуска
Ленивые цепочки создают рецепт, но не выполняют его. Завершающий метод, такой как first, to_a или force, запускает вычисления.
chain = (1..Float::INFINITY).lazy.map { |n| n * n }
puts "Nothing computed yet"
p chain.first(4)Получение результатов
force (псевдоним to_a) преобразует ограниченную ленивую цепочку в массив.
result = (1..20).lazy.select(&:odd?).first(5)
p result
all = (1..6).lazy.map { |n| n * 10 }.force
p allЛенивая обработка в цепочке
Несколько ленивых операций чередуются для каждого элемента, а не выполняются как отдельные полные проходы. Каждое значение проходит через всю цепочку, прежде чем начнётся обработка следующего.
result = (1..Float::INFINITY)
.lazy
.map { |n| n * n }
.select { |n| n.even? }
.first(4)
p resulttake и ограничение по условию
Ленивые take и take_while прекращают получение значений, как только выполняется их условие.
result = (1..Float::INFINITY).lazy.take_while { |n| n < 6 }.to_a
p resultБесконечные последовательности
Ленивые перечислители особенно полезны с генераторами. Объединяйте их с Enumerator, чтобы моделировать бесконечные потоки.
naturals = Enumerator.new do |y|
n = 1
loop { y << n; n += 1 }
end
p naturals.lazy.map { |x| x * 3 }.first(5)Эффективное использование памяти
Поскольку ленивые цепочки не создают полностью промежуточную коллекцию, они экономят память при отборе нескольких результатов из большого объёма данных.
big = (1..1_000_000).lazy
first_match = big.select { |n| n % 7 == 0 && n % 11 == 0 }.first
puts first_matchКогда использовать ленивые вычисления
Используйте ленивые вычисления, когда:
- Источник бесконечен или очень велик.
- Вам нужно всего несколько результатов.
- Вы хотите избежать создания больших промежуточных массивов.
Для небольших коллекций обычные методы проще и достаточно быстры.
fizz = (1..Float::INFINITY).lazy.select { |n| n % 3 == 0 }.first(5)
p fizzСобираем всё вместе
Ленивые перечислители откладывают вычисления:
.lazyделает цепочку ленивой.- Вычисления выполняются только тогда, когда завершающий метод запрашивает значения.
- Это идеально подходит для бесконечных и огромных последовательностей.
squares = (1..Float::INFINITY).lazy.map { |n| n * n }
p squares.select(&:odd?).first(4)Быстрая проверка
Проверьте, насколько хорошо Вы поняли ленивые перечислители.
Повторение
Вы изучили ленивые перечислители:
.lazyоткладывает вычисления.- Завершающие методы (
first,to_a,force) запускают вычисления. - Каждое значение по запросу проходит через всю цепочку.
- Это идеальный вариант для бесконечных или больших последовательностей.
p (1..Float::INFINITY).lazy.select(&:even?).map { |n| n + 1 }.first(3)Часто задаваемые вопросы
Урок «Ленивые перечислители» бесплатный?
Да — полный текст урока «Ленивые перечислители» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Ruby Academy, подпишись на CoddyKit PRO. Курс Ruby Academy содержит 4 уроков всего.
Чему я научусь в уроке «Ленивые перечислители»?
Ленивое вычисление Ты практикуешь Ruby Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Ruby Academy?
Предыдущий опыт не требуется. Ruby Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.
Сколько времени занимает урок «Ленивые перечислители»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Ruby Academy?
Да. Каждый урок Ruby Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Написание собственного each
- Подключение Enumerable
- Ленивые перечислители
- Объекты Enumerator