Чтение онлайн

на главную - закладки

Жанры

JavaScript. Подробное руководство, 6-е издание
Шрифт:

}

// Обрабатываемый текст

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 && 1ine[0] !=

});

// Теперь извлечь отфильтрованные строки из конвейера и обработать их,

// остановиться, если встретится строка “quit",

for (let line in nonblank) {

if (line === "quit") break; console.log(line);

}

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

send,
который перезапускает генератор подобно методу
next.
Разница лишь в том, что методу
send
можно передать значение, которое станет значением, возвращаемым выражением
yield
в функции-генераторе. (В большинстве генераторов, которые не принимают дополнительных входных данных, ключевое слово
yield
выглядит как инструкция. Однако в действительности
yield
– это выражение, возвращающее значение.) Кроме методов
next
и
send
существует еще один способ перезапустить генератор - метод
throw.
Если вызвать этот метод, выражение
yield
возбудит аргумент метода
throw
как исключение, как показано в следующем примере:

// Функция-генератор, ведущая счет от заданного начального значения.

// Метод send позволяет увеличить счетчик на определенное значение.

// Вызов throw("reset") сбрасывает счетчик в начальное значение.

// Это всего лишь пример - здесь метод throw используется не самым лучшим образом,

function counter(initial) {

let nextValue = initial; // Сохранить начальное значение

while(true) {

try {

let increment = yield nextValue; // Вернуть значение и получить приращение

if (increment) // Если передано приращение...

nextValue += increment; // ...использовать его.

else nextValue++; // Иначе увеличить на 1

}

catch (e) { // Если был вызван метод

if (e==="reset") // throw генератора

nextValue = initial; else throw e;

}

}

}

let c = counter(10); //
Создать генератор с начальным значением 10

console.log(c.next); //Выведет 10

console.log(c.send(2)); // Выведет 12

console.log(c.throw("reset")); // Выведет 10

11.4.4. Генераторы массивов

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

Ниже приводится пример генератора массивов, использующего созданную выше функцию range для инициализации массива, содержащего квадраты четных чисел, меньшие 100:

let evensquares = [х*х for (х in range(0,10)) if (х % 2 === 0)]

Эта строка примерно эквивалентна следующим пяти строкам:

let evensquares = [];

for(x in range(0,10)) {

if (x % 2 === 0)

evensquares.push(x*x);

}

В общем случае синтаксис генераторов массивов имеет следующий вид:

[ выражение for ( переменная in объект ) if ( условное выражение ) ]

Обратите внимание на три основные части в квадратных скобках:

• Цикл

for/in
или
for/each
без тела. Эта часть генератора массивов включает переменную (или несколько переменных при использовании присваивания с разложением) слева от ключевого слова
in
и объект (который может быть генератором, итерируемым объектом или массивом) справа от ключевого слова
in
. Несмотря на отсутствие тела цикла, эта часть генератора массивов выполняет итерации и присваивает последовательные значения, определяемые переменной. Обратите внимание, что перед именем переменной не допускается указывать ключевое слово
var
или
let
– генераторы массивов неявно используют ключевое слово
let
, а используемая переменная недоступна за пределами квадратных скобок и не затирает существующую переменную с тем же именем.

• После итерируемого объекта может присутствовать ключевое слово

if
и условное выражение. Если оно присутствует, условное выражение используется для фильтрации значений, по которым выполняются итерации. Условное выражение вычисляется после получения каждого значения, воспроизводимого циклом
for
. Если результатом выражения является
false
, это значение пропускается и в массив ничего не добавляется. Ключевое слово
if
можно не указывать - если оно отсутствует, генератор массива действует так, как если бы в нем присутствовала конструкция
if (true)
.

Поделиться:
Популярные книги

Князь Андер Арес 4

Грехов Тимофей
4. Андер Арес
Фантастика:
фэнтези
героическая фантастика
боевая фантастика
попаданцы
5.00
рейтинг книги
Князь Андер Арес 4

Афганский рубеж 4

Дорин Михаил
4. Рубеж
Фантастика:
попаданцы
альтернативная история
6.00
рейтинг книги
Афганский рубеж 4

Память льда

Эриксон Стивен
3. «Малазанская империя»
Фантастика:
фэнтези
6.00
рейтинг книги
Память льда

Неучтенный элемент. Том 11

NikL
11. Антимаг. Вне системы
Фантастика:
фэнтези
5.00
рейтинг книги
Неучтенный элемент. Том 11

Камень. Книга 3

Минин Станислав
3. Камень
Фантастика:
фэнтези
боевая фантастика
8.58
рейтинг книги
Камень. Книга 3

Двойник короля 12

Скабер Артемий
12. Двойник Короля
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Двойник короля 12

Распутье

Басаргин Иван Ульянович
Сибириада
Проза:
военная проза
историческая проза
5.00
рейтинг книги
Распутье

Черный Маг Императора 18

Герда Александр
18. Черный маг императора
Фантастика:
юмористическое фэнтези
аниме
сказочная фантастика
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Черный Маг Императора 18

Звездная Кровь. Экзарх III

Рокотов Алексей
3. Экзарх
Фантастика:
боевая фантастика
попаданцы
рпг
5.00
рейтинг книги
Звездная Кровь. Экзарх III

Двойник короля 14

Скабер Артемий
14. Двойник Короля
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Двойник короля 14

Газлайтер. Том 26

Володин Григорий Григорьевич
26. История Телепата
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Газлайтер. Том 26

Мечник Вернувшийся 1000 лет спустя

Ткачев Андрей Юрьевич
1. Вернувшийся мечник
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Мечник Вернувшийся 1000 лет спустя

Школа пластунов

Трофимов Ерофей
Одиночка
Фантастика:
боевая фантастика
5.00
рейтинг книги
Школа пластунов

Сердце Дракона. Том 11

Клеванский Кирилл Сергеевич
11. Сердце дракона
Фантастика:
фэнтези
героическая фантастика
боевая фантастика
6.50
рейтинг книги
Сердце Дракона. Том 11