Yield ключевое слово

Тренажер по PHP для пользователей с начальным уровнем подготовки.

Тренажер PHP

Генераторы в PHP — это мощный инструмент для создания итераторов без лишних сложностей. Вместо того чтобы создавать в памяти огромный массив данных и возвращать его, генератор позволяет "отдавать" значения по одному, как только они понадобятся. Это достигается с помощью ключевого слова `yield`.

Ключевое отличие от обычных функций в том, что `yield` приостанавливает выполнение генератора, запоминает его состояние и возвращает значение. При следующем обращении к генератору выполнение возобновляется с того же места. Такой подход невероятно эффективен по памяти, особенно при работе с большими файлами, базами данных или бесконечными последовательностями.

В этом тренажере вы научитесь создавать простые и сложные генераторы, использовать `yield` для возврата значений и ключей, а также поймете ключевые отличия генераторов от традиционных функций, возвращающих массивы.

Список тем

Создание простого генератора

id: 39312_task_gen_1

Превратите эту функцию в генератор. Вместо того чтобы собирать все числа в массив, функция должна "отдавать" каждое число по одному прямо в цикле. Для этого нужно использовать специальное ключевое слово.

Заполните пропуски
function numberRange(int $start, int $end) {
    for ($i = $start; $i <= $end; $i++) {
        input1S $i;
    }
}

foreach (numberRange(1, 3) as $number) {
    echo "$number ";
}
Сообщения
Проверить
Показать решение на 3 сек.
Показать подсказку

Первое значение генератора

id: 39312_task_gen_2

Генератор выполняется "лениво", то есть код внутри него не работает, пока не запрошено первое значение. Что выведет этот скрипт, который запрашивает только один элемент?

Выберите правильный вариант ответа
function getLetters() {
    echo "Start ";
    yield 'A';
    echo "Middle ";
    yield 'B';
    echo "End ";
}

foreach (getLetters() as $letter) {
    echo $letter;
    break;
}
Сообщения
Проверить
Показать подсказку

Ошибка: `return` вместо `yield`

id: 39312_task_gen_3

Эта функция должна генерировать числа от 1 до 3, но вместо этого она сразу завершает работу после первого числа. Найдите строку с логической ошибкой и исправьте ее, чтобы функция стала полноценным генератором.

Найдите ошибку и исправьте
function count_to_three() {
    for ($i = 1; $i <= 3; $i++) {
        return $i;
    }
}
 
foreach (count_to_three() as $num) {
    echo $num;
}
Сообщения
Проверить
Показать решение на 3 сек.
Показать подсказку

Сборка файлового ридера

id: 39312_task_gen_4

Соберите из фрагментов кода функцию-генератор, которая построчно читает файл. Такой подход очень эффективен, так как не загружает весь файл в память. Лишние фрагменты использовать не нужно.

Перетяните в правильном порядке строки из одного блока в другой
function readFileGenerator($filename) {
$file = fopen($filename, 'r');
while (($line = fgets($file)) !== false) {
yield $line;
}
fclose($file);
return $file;
$lines[] = $line;
Сообщения
Проверить
Показать решение на 3 сек.
Показать подсказку

Что в итоге?

id: 39312_task_gen_5

Проанализируйте этот генератор и цикл. Какая строка будет выведена в результате работы кода? Введите итоговую строку без кавычек.

Что должно получиться?
function getAcronym() {
    yield 'P';
    yield 'H';
    yield 'P';
}

$parts = [];
foreach (getAcronym() as $char) {
    $parts[] = $char;
}
$result = implode('-', $parts);

echo $result;
Сообщения
Проверить
Показать подсказку

Генерация пар ключ-значение

id: 39312_task_gen_6

Генераторы могут возвращать не только значения, но и ключи, как в ассоциативных массивах. Дополните код, чтобы он генерировал пары "ключ => значение" для элементов исходного массива.

Заполните пропуски
function arrayWithKeys(array $data) {
    foreach ($data as $key => $value) {
        yield input1S => input2S;
    }
}

$items = ['a' => 'Apple', 'b' => 'Banana'];

foreach (arrayWithKeys($items) as $key => $value) {
    echo "$key: $value; ";
}
Сообщения
Проверить
Показать решение на 3 сек.
Показать подсказку

Повторная итерация генератора

id: 39312_task_gen_7

Генератор — это итератор одноразового использования. Его нельзя "перемотать" назад. Что выведет этот код, который пытается пройти по одному и тому же экземпляру генератора дважды?

Выберите правильный вариант ответа
function getNumbers() {
    yield 1;
    yield 2;
}

$generator = getNumbers();

foreach ($generator as $number) {
    echo $number;
}

echo '-';

// Попытка повторной итерации
foreach ($generator as $number) {
    echo $number;
}
Сообщения
Проверить
Показать подсказку

Делегирование с `yield from`

id: 39312_task_gen_8

Вместо того чтобы вручную перебирать один генератор внутри другого, можно "делегировать" ему работу. Вставьте правильную конструкцию из банка, чтобы генератор `mainGenerator` сначала вернул свои значения, а затем все значения из `subGenerator`.

Нужно правильно расставить в пропуски предложенные варианты
function subGenerator() {
    yield 3;
    yield 4;
}

function mainGenerator() {
    yield 1;
    yield 2;
    input1S subGenerator();
    yield 5;
}

foreach (mainGenerator() as $num) {
    echo "$num ";
}
yield from
yield
return
include
Сообщения
Проверить
Показать решение на 3 сек.
Показать подсказку

Генератор против Массива

id: 39312_task_gen_9

Сопоставьте утверждения с подходом, который они описывают. Какой из них эффективен по памяти, а какой возвращает все данные сразу?

Сопоставьте строки в правой части с соответствующими строками в левой по порядковому номеру
Высокое потребление памяти при больших наборах данных
Низкое потребление памяти, значения генерируются по требованию
Все значения вычисляются и возвращаются единым блоком
Значения возвращаются по одному, выполнение приостанавливается
Функция, возвращающая массив (return)
Функция-генератор (yield)
Функция-генератор (yield)
Функция, возвращающая массив (return)
Сообщения
Проверить
Показать подсказку
НайтиКурс.Ру