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

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

29.04.2020, 15:01. Показов 2886. Ответов 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
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
29.04.2020, 15:01
Ответы с готовыми решениями:

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

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

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

9
 Аватар для diadiavova
7253 / 2601 / 743
Регистрация: 11.04.2015
Сообщений: 4,137
Записей в блоге: 43
30.04.2020, 00:54
Лучший ответ Сообщение было отмечено 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  [ТС]
diadiavova, спасибо! Теперь стало ясно. В принципе я так и думал, что туда-обратно идет посследовательность вызовов next генераторов, только не мог понять откуда. Сперва думал, что сверху, так как trimmed в своем for/in начинает типа у себя интерировать lines. Но после вашего разъяснения все еще раз обдумал и понял, что при первом движении сверху только создаются генераторы, а вызов их методов next начинается снизу. Спасибо)
0
Эксперт JS
6496 / 3906 / 2006
Регистрация: 14.06.2018
Сообщений: 6,781
30.04.2020, 14:40
Лучший ответ Сообщение было отмечено 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  [ТС]
amr-now, а чем в данном случае for/in отличается от for/of ?
0
Эксперт JS
6496 / 3906 / 2006
Регистрация: 14.06.2018
Сообщений: 6,781
30.04.2020, 14:55
svisch, for/of является перебором живых элементов из несуществующей последовательности, которую возвращает функция-генератор.

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

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

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

Вот свежая информация по генераторам:
https://learn.javascript.ru/generators
Данный сайт, можно сказать, рекомендован для внимательного прочтения специалистам по JavaScript. Даже старик иногда может найти там интересную статью.
1
2 / 2 / 2
Регистрация: 26.10.2015
Сообщений: 83
30.04.2020, 17:50  [ТС]
amr-now, спасибо!
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
30.04.2020, 17:50
Помогаю со студенческими работами здесь

Принцип работы баттон-генераторов
Хотелось бы узнать, как работают генераторы кнопок, риббонов, например, вот этот? http://livetools.uiparade.com/ribbon-builder.html

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Новые блоги и статьи
Логирование в C# ASP.NET Core с помощью Serilog, ElasticSearch, Kibana
stackOverflow 25.04.2025
Помните те времена, когда для анализа проблемы приходилось подключаться к серверу, искать нужный лог-файл среди десятков других и вручную фильтровать тысячи строк в поисках ошибки? К счастью, эти дни. . .
Структура "железный OnKeyUp" вместо антидребезга. Полностью асинхронный счётчик.
Hrethgir 25.04.2025
Программа для симуляции схемы - Logisim Evolution В общем какое-то время отвлёкся, так было надо, теперь когда запилю это на verilog и FPGA , досоставлю заявку в ФИПС на полезную модель - не готов. . .
Автоматизация Amazon Web Services (AWS) с Boto3 в Python
py-thonny 25.04.2025
Облачные вычисления стали неотъемлемой частью современной ИТ-инфраструктуры, а Amazon Web Services (AWS) занимает лидирующие позиции среди провайдеров облачных услуг. Управление многочисленными. . .
Apache Kafka vs RabbitMQ в микросервисной архитектуре
ArchitectMsa 25.04.2025
Современная разработка ПО всё чаще склоняется к микросервисной архитектуре — подходу, при котором приложение разбивается на множество небольших, автономных сервисов. В этой распределённой среде. . .
Параллельное программирование с OpenMP в C++
NullReferenced 24.04.2025
Параллельное программирование — подход к созданию программ, когда одна задача разбивается на несколько подзадач, которые могут выполняться одновременно. Оно стало необходимым навыком для. . .
Цепочки методов в C# с Fluent API
UnmanagedCoder 24.04.2025
Современное программирование — это не только решение функциональных задач, но и создание кода, который удобно поддерживать, расширять и читать. Цепочки методов и Fluent-синтаксис в C# стали мощным. . .
Мульти-тенантные БД с PostgreSQL Row Security
Codd 23.04.2025
Современные облачные сервисы и бизнес-приложения всё чаще обслуживают множество клиентов в рамках единой программной инфраструктуры. Эта архитектурная модель, известная как мульти-тенантность, стала. . .
Реализация конвейеров машинного обучения с Python и Scikit-learn
AI_Generated 23.04.2025
Мир данных вокруг нас растёт с каждым днём, и умение эффективно обрабатывать информацию стало необходимым навыком. Специалисты по машинному обучению ежедневно сталкиваются с задачами предобработки. . .
Контроллеры Kubernetes Ingress: Сравнительный анализ
Mr. Docker 23.04.2025
В Kubernetes управление входящим трафиком представляет собой одну из ключевых задач при построении масштабируемых и отказоустойчивых приложений. Ingress — это API-объект, который служит вратами. . .
Оптимизация кода Python с Cython и Numba
py-thonny 23.04.2025
Python прочно обосновался в топе языков программирования благодаря своей простоте и гибкости. Разработчики любят его за читабельность кода и богатую экосистему библиотек. Но у этой медали есть и. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru
Выделить код Копировать код Сохранить код Нормальный размер Увеличенный размер