0Pricing
Ruby Academy · Урок

Ленивые перечислители

Ленивое вычисление

«Ленивые перечислители» — бесплатный урок 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 result

take и ограничение по условию

Ленивые 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 — локальная установка не требуется.

Все уроки этого курса

  1. Написание собственного each
  2. Подключение Enumerable
  3. Ленивые перечислители
  4. Объекты Enumerator
← Назад к Ruby Academy