Форум программистов, компьютерный форум, киберфорум
JavaScript для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.93/15: Рейтинг темы: голосов - 15, средняя оценка - 4.93
2 / 2 / 2
Регистрация: 26.10.2015
Сообщений: 83
1

Цепочка вызовов генераторов

29.04.2020, 15:01. Показов 2840. Ответов 9
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Здравствуйте. Помогите разобраться в примере цепочки вызовов генераторов из примера в книжке:
Javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
//генератор, возвращающий строки текста по одной
function eachline(s) {
let p;
while((p = s.indexOf('\n')) != -1) {
  yield s.substring(0,p);
  s = s.substring(p+1);
  }
  if(s.length > 0) yield s;
}
 
//функция-генератор, возвращающая f(x) для каждого элемента x интерируемого объекта
function map(i,f) {
  for(let x in i) yeild f(x);
}
 
//функция-генератор, возвращающая элементы i, для которых f(x) возвращает true
function select(i,f) {
  for(let x in i) {
    if(f(x)) yield x;
  }
}
 
//обрабатываемый текст
let text = " #comment \n \n hello \nworld\n quit \n unreached \n";
 
//сконструировать конвейер генераторов для обработки текста
//сперва разбить текст на строки
let lines = eachline(text);
//затем удалить начальные и конечные пробелы в каждой строке
let trimmed = map(lines, function(line) {return line.trim();});
//наконец, игнорировать пустые строки и комментарии
let nonblank = select(trimmed, function(line) {
  return line.length >0 && line[0] != "#"
});
 
//теперьь извлечь отфильтрованные строки из конвейера и обработать их, остановиться, если встретиться строка "quit"
for(let line in nonblank) {
  if(line === "quit") break;
  console.log(line);
}
Вопрос в следующем. Как идут вызовы генераторов. Ведь из книжки я понял, что при встрече оператора yield интерация останавливается и эначение становиться возвращающем метода next() генератора.
Здесь же не пойму откуда куда поднимается цепочка, или же обработка идет последовательно: сперва разбивается строка на подстроки (тогда куда они сохраняются все?), потом подстроки обрезаются и т.д. Но тогда у меня не сходится в голове следующее. Вот возьмем trimmed. Этот генератор начинает обрезать пробелы подстрок интерируя генератор lines. Но все же подстроки не будут проинтерироавны поскольку при первой встрече yield генератор вернет значение.
буду рад за подробное объяснение примера. Спасибо
1
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
29.04.2020, 15:01
Ответы с готовыми решениями:

Цепочка вызовов и передача аргументов
Если делегат ссылается на цепочку методов (в примере ниже на методы one и two), то всем методам...

Микросхемы кварцевых генераторов
С удивлением обнаружил, что сабж не только существует, но и вполне доставаем, разнообразен и...

Теория БесТопливных Генераторов
Кто верит в БТГ? Есть ли у кого рабочие схемы?

Принцип работы баттон-генераторов
Хотелось бы узнать, как работают генераторы кнопок, риббонов, например, вот этот?...

9
6266 / 2505 / 738
Регистрация: 11.04.2015
Сообщений: 4,041
Записей в блоге: 43
30.04.2020, 00:54 2
Лучший ответ Сообщение было отмечено svisch как решение

Решение

svisch, если коротко, то каждый вызов проходит полный путь по цепочке туда-обратно.
Начинается обработка с цикла в конце листинга. В каждой его итерации происходит следующая последовательность действий:
1. Вызывается next у nonblank.
2. При этом nonblank начинает вызывать next у trimmed и делает это до тех пор, пока не получит непустую строку.
3. У самого trimmed вызов next переадресуется lines.
4. Вызов next у lines приводит к тому, что из исходного текста отрезается очередная строка и возвращается. Здесь начинается движение в обратном направлении.
5. От lines строка попадает к trimmed, который ее очищает от пробелов с краев и возвращает дальше по цепочке nonblank
6. Здесь, как уже говорилось строка проверяется на наличие символов и если их нет, запрос повторяется пока не будет получено то что надо и это будет возвращено запрашивающей стороне.
7. В следующих итерациях вся эта последовательность будет повторяться.
2
2 / 2 / 2
Регистрация: 26.10.2015
Сообщений: 83
30.04.2020, 13:23  [ТС] 3
diadiavova, спасибо! Теперь стало ясно. В принципе я так и думал, что туда-обратно идет посследовательность вызовов next генераторов, только не мог понять откуда. Сперва думал, что сверху, так как trimmed в своем for/in начинает типа у себя интерировать lines. Но после вашего разъяснения все еще раз обдумал и понял, что при первом движении сверху только создаются генераторы, а вызов их методов next начинается снизу. Спасибо)
0
Эксперт JS
6494 / 3905 / 2005
Регистрация: 14.06.2018
Сообщений: 6,781
30.04.2020, 14:40 4
Лучший ответ Сообщение было отмечено amr-now как решение

Решение

Здравствуйте.
Цитата Сообщение от svisch Посмотреть сообщение
Как идут вызовы генераторов.
Никак не идут. Вызовы на месте стоят. Код был нерабочий с множеством ошибок.
Вот рабочий код:
Javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
//генератор, возвращающий строки текста по одной
function* eachline(s) {
    let p;
    while ((p = s.indexOf('\n')) != -1) {
        yield s.substring(0, p);
        s = s.substring(p + 1);
    }
    if (s.length > 0)
        yield s;
}
//функция-генератор, возвращающая f(x) для каждого элемента x интерируемого объекта
function* map(i, f) {
    for (let x of i)
        yield f(x);
}
//функция-генератор, возвращающая элементы i, для которых f(x) возвращает true
function* select(i, f) {
    for (let x of i) {
        if (f(x))
            yield x;
    }
}
//обрабатываемый текст
let text = " #comment \n \n hello \nworld\n quit \n unreached \n";
//сконструировать конвейер генераторов для обработки текста
//сперва разбить текст на строки
let lines = eachline(text);
//затем удалить начальные и конечные пробелы в каждой строке
let trimmed = map(lines, function (line) { return line.trim(); });
//наконец, игнорировать пустые строки и комментарии
let nonblank = select(trimmed, function (line) {
    return line.length > 0 && line[0] != "#";
});
//теперь извлечь отфильтрованные строки из конвейера и обработать их, остановиться, если встретиться строка "quit"
for (let line of nonblank) {
    if (line === "quit")
        break;
    console.log(line);
}
Добавлено через 15 минут
Важно понять:
- функция-генератор не возвращает никакого осязаемого объекта. Она возвращает виртуальную последовательность, которую можно перебирать.

for (let item of sequence) - означает: Для каждого элемента item последовательности sequence сделать следующие действия.

То есть сначала обратились к неосязаемой последовательности nonblank,
которая оказалась последовательностью-результатом функции select,
которая в свою очередь взяла аргументом trimmed и преобразовала в новую последовательность и так далее.

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

Добавлено через 5 минут
---
Удобно данный процесс воспринимать так:
1) получили несуществующий виртуальный массив сырых строк.
2) получили несуществующий виртуальный массив строк без начальных и конечных пробелов.
3) Получили несуществующий виртуальный массив непустых строк, которые не являются комментариями.
4) А теперь начали перебирать несуществующий виртуальный массив и по очереди получать реальные живые элементы.
2
2 / 2 / 2
Регистрация: 26.10.2015
Сообщений: 83
30.04.2020, 14:45  [ТС] 5
amr-now, а чем в данном случае for/in отличается от for/of ?
0
Эксперт JS
6494 / 3905 / 2005
Регистрация: 14.06.2018
Сообщений: 6,781
30.04.2020, 14:55 6
svisch, for/of является перебором живых элементов из несуществующей последовательности, которую возвращает функция-генератор.

for/in является циклом, который перебирает названия свойств у живого объекта типа Object или типа-потомка Object.

Добавлено через 7 минут
svisch, книжка что-ли описывает экспериментальную технологию генераторов? Какого года издание?
0
2 / 2 / 2
Регистрация: 26.10.2015
Сообщений: 83
30.04.2020, 15:25  [ТС] 7
amr-now, 2016 г. Фленаган "Подробное руководство"
0
6266 / 2505 / 738
Регистрация: 11.04.2015
Сообщений: 4,041
Записей в блоге: 43
30.04.2020, 15:35 8
Цитата Сообщение от svisch Посмотреть сообщение
а чем в данном случае for/in отличается от for/of ?
Они отличаются не в данном случае, а в принципе. Тут дело вот в чем. В ряде языков конструкции типа for...in foreach...in и т.п. действительно используются для неиндексируемого перебора элементов коллекций и это может сбивать с толку. Дело в том, что так уж исторически сложилось, что в JS не было такой конструкции довольно долго, однако for...in существует уже давно и существует од для перебора имен свойств объекта. Ну то есть у объекта {x:1, y:2} он выдаст поочередно сначала "x", потом "y". А вот когда решили все-таки добавить возможность такого перебора, то как-то это все дело надо было обозвать, а фор-ин уже был занят. Ну как-то так.
1
Эксперт JS
6494 / 3905 / 2005
Регистрация: 14.06.2018
Сообщений: 6,781
30.04.2020, 15:35 9
svisch, за три года синтаксис языка устаревает насмерть.
Старые книжки можно читать, только если там будет подробное практическое описание некоего домашнего проекта сайта. Для набивки руки на псевдо-практике.

И то специалисты-дизайнеры скажут, что в старой вёрстке много фуфла и отстоя.

Вот свежая информация по генераторам:
https://learn.javascript.ru/generators
Данный сайт, можно сказать, рекомендован для внимательного прочтения специалистам по JavaScript. Даже старик иногда может найти там интересную статью.
1
2 / 2 / 2
Регистрация: 26.10.2015
Сообщений: 83
30.04.2020, 17:50  [ТС] 10
amr-now, спасибо!
0
30.04.2020, 17:50
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
30.04.2020, 17:50
Помогаю со студенческими работами здесь

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

Определение тока методом эквивалентных генераторов
Методом эквивалентного генератора определить ток I5 Дошёл до момента преобразования схемы из...

Схемы генераторов помех радиоэфира (радиоглушителей)
Создал тему что бы в ней пользователи выкладывали схемы генераторов помех радио эфира - т.н. радио...

Альтернативные варианты генераторов XMLSchema (*.xsd)
Мудаки из Seebeyond намудрили с их Development IDE и поетому JAXB out of scope (причину описывать...

Подскажите несколько генераторов случайных чисел на Си
Дали задание сравнить несколько ГСЧ, а я знаю только функцию rand(); в stdlib.h. Есть ли еще...

Оптимизация поиска линейных конгруэнтных генераторов
Здравствуйте! Хотел попросить помощи со следующим заданием: необходимо вернуть количество возможных...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru