Iterator.zip()
Статический метод Iterator.zip() создает новый объект Iterator, который агрегирует элементы из нескольких итерируемых объектов, выдавая массивы, содержащие элементы на одной позиции. По сути, он "объединяет" входные итерируемые объекты, позволяя одновременно итерировать по ним.
Метод Iterator.zipKeyed() похож, но выдает объекты вместо массивов с указанными вами ключами.
Синтаксис
Iterator.zip(iterables) Iterator.zip(iterables, options)
Параметры
-
iterables - Итерируемый объект, содержащий итерируемые объекты, элементы которых агрегируются. Он должен быть итерируемым и не может быть итератором. Он должен быть конечным, хотя его элементы могут быть бесконечными итерируемыми объектами. Каждый элемент должен реализовывать либо протокол итерируемого объекта, либо, в противном случае, протокол итератора. Строки не допускаются: чтобы объединить строки, явно преобразуйте их в итераторы с помощью
Iterator.from(). -
optionsНеобязательный - Объект, определяющий поведение в случае несоответствия длин входных данных. Он может иметь следующие свойства:
-
modeНеобязательный - Одно из следующих значений:
-
"shortest"(по умолчанию): Результирующий итератор останавливается, когда один из входных итерируемых объектов исчерпан. -
"longest": Результирующий итератор останавливается, когда все входные итерируемые объекты исчерпаны. Отсутствующие значения из более коротких итерируемых объектов заполняются в соответствии с опциейpadding. -
"strict": Будет выброшено исключениеTypeError, если не все входные итерируемые объекты завершаются одновременно.
-
-
paddingНеобязательный - Итерируемый объект (не итератор). Извлекается и проверяется только при
mode==="longest". Еслиundefinedили отсутствует, отсутствующие значения из более коротких итерируемых объектов заполняютсяundefined(что эквивалентно передаче пустого итерируемого объекта). Если предоставлен итерируемый объект, он итерируется такое количество раз, сколько элементов вiterables, *как только будет вызванIterator.zip()*.padding[i]используется для отсутствующих значений изiterables[i](при условии, чтоpaddingиiterablesпредоставлены в виде массивов; они не обязательно должны быть таковыми). Еслиpaddingкорочеiterables,undefinedиспользуется для оставшихся итерируемых объектов.
-
Возвращаемое значение
Новый объект Iterator. Каждый из его элементов является массивом длиной, равной количеству входных итерируемых объектов, содержащим элементы из каждого входного итерируемого объекта в соответствующей позиции. Если объект iterables пуст, результирующий итератор создается как завершенный.
Описание
Функция Iterator.zip() ведет себя подобно операции транспонирования, выдавая массивы, содержащие элементы на соответствующих позициях в каждом из входов. Если представить итерируемые объекты как массивы, входные данные могут выглядеть следующим образом:
[ [a1, a2, a3, a4], // Iterable a [b1, b2, b3], // Iterable b [c1, c2, c3, c4, c5], // Iterable c ];
Результирующий итератор, независимо от опций, начнет с выдачи следующих массивов:
[a1, b1, c1]; [a2, b2, c2]; [a3, b3, c3];
После выдачи первых трех массивов входной итерируемый объект b исчерпывается при четвертом вызове next() — он возвращает { done: true }. Что произойдет дальше, зависит от опции mode. Если mode равен "shortest" (по умолчанию), результирующий итератор останавливается здесь: два других входных итератора закрываются. Если mode равен "strict", возникает ошибка, поскольку два других итерируемых объекта *не* завершились, когда второй выдает результат { done: true }. Если mode равен "longest", результирующий итератор продолжает выдавать массивы, заполняя отсутствующие значения. Например, если padding не предоставлено, по умолчанию используется undefined:
[a4, undefined, c4]; [undefined, undefined, c5];
Если padding предоставлен как итерируемый объект, поскольку существует три входных итерируемых объекта, первые три значения из итерируемого объекта padding используются для заполнения отсутствующих значений. Предположим, что padding — это массив со значениями [p1, p2, p3]. Тогда p2 используется для заполнения отсутствующего значения из входного итерируемого объекта b, а p1 используется для заполнения отсутствующего значения из входного итерируемого объекта a:
[a4, p2, c4]; [p1, p2, c5];
Если итерируемый объект padding содержит менее трех значений, оставшиеся отсутствующие значения заполняются undefined.
Примеры
Итерация по карте с индексами
Используя Iterator.zip(), вы можете итерировать по любому итерируемому объекту (строки по умолчанию не поддерживаются), имея при этом доступ к инкрементируемому счетчику:
const ages = new Map([
["Caroline", 30],
["Danielle", 25],
["Evelyn", 35],
]);
const numbers = (function* () {
let n = 0;
while (true) {
yield n++;
}
})();
for (const [index, [name, age]] of Iterator.zip([numbers, ages])) {
console.log(`${index}: ${name} is ${age} years old.`);
}
// Output:
// 0: Caroline is 30 years old.
// 1: Danielle is 25 years old.
// 2: Evelyn is 35 years old.
numbers — это бесконечный итератор, который генерирует инкрементирующиеся числа, начиная с 0. Поскольку Iterator.zip() по умолчанию останавливается, когда самый короткий входной итерируемый объект исчерпан, цикл выполняется ровно три раза. Итератор numbers корректно закрывается после завершения цикла; он не вызывает бесконечный цикл.
Создание Map из списков ключей и значений
Предположим, у вас есть два массива: один с ключами, другой со значениями. Вы можете использовать Iterator.zip() для объединения их в Map:
const days = ["Mon", "Tue", "Wed", "Thu", "Fri"];
const temperatures = [22, 21, 23, 20, 19];
const dayTemperatureMap = new Map(Iterator.zip([days, temperatures]));
console.log(dayTemperatureMap);
// Map(5) { 'Mon' => 22, 'Tue' => 21, 'Wed' => 23, 'Thu' => 20, 'Fri' => 19 }
Совместная итерация по нескольким источникам данных
Предположим, у вас есть данные из нескольких источников, таких как несколько микросервисов или баз данных. Вы знаете, что каждый источник предоставляет связанные данные в одном порядке, и вы хотите обрабатывать их вместе. Вы можете использовать Iterator.zip() для достижения этой цели:
const names = fetchNames(); // e.g., ["Caroline", "Danielle", "Evelyn"]
const ages = fetchAges(); // e.g., [30, 25, 35]
const cities = fetchCities(); // e.g., ["New York", "London", "Hong Kong"]
for (const [name, age, city] of Iterator.zip([names, ages, cities])) {
console.log(`${name}, aged ${age}, lives in ${city}.`);
}
// Output:
// Caroline, aged 30, lives in New York.
// Danielle, aged 25, lives in London.
// Evelyn, aged 35, lives in Hong Kong.
Предоставление заполнения для неровных итерируемых объектов
При объединении итерируемых объектов разной длины с mode, установленным в "longest", вы можете предоставить итерируемый объект padding, чтобы указать значения, используемые для заполнения отсутствующих записей:
const letters = ["a", "b", "c", "d", "e"];
const numbers = [1, 2, 3];
// One padding value per iterable
const padding = ["[Letter missing]", "[Number missing]"];
const it = Iterator.zip([letters, numbers], { mode: "longest", padding });
for (const [letter, number] of it) {
console.log(`${letter}: ${number}`);
}
// Output:
// a: 1
// b: 2
// c: 3
// d: [Number missing]
// e: [Number missing]
Объединение строк
Строки не принимаются в качестве входных итерируемых объектов для Iterator.zip(), поскольку теперь считается ошибкой делать строки неявно итерируемыми. Чтобы объединить строки, явно преобразуйте их в итераторы с помощью Iterator.from():
const str1 = "abc";
const str2 = "1234";
const it = Iterator.zip([Iterator.from(str1), Iterator.from(str2)]);
for (const [char1, char2] of it) {
console.log(`${char1} - ${char2}`);
}
// Output:
// a - 1
// b - 2
// c - 3
В некоторых случаях вы можете захотеть разделить по графемам, а не по кодовым единицам. В этом случае вы можете использовать API Intl.Segmenter:
const segmenter = new Intl.Segmenter("en-US", { granularity: "grapheme" });
const str1 = "🤷♂️🤷♀️🤷";
const str2 = "123";
const it = Iterator.zip([
segmenter.segment(str1).map(({ segment }) => segment),
segmenter.segment(str2).map(({ segment }) => segment),
]);
for (const [char1, char2] of it) {
console.log(`${char1} - ${char2}`);
}
// Output:
// 🤷♂️ - 1
// 🤷♀️ - 2
// 🤷 - 3
Спецификации
| Спецификация |
|---|
| Совместная итерация # sec-IteratorZip |
Совместимость с браузерами
| Настольные компьютеры | Мобильные устройства | Сервер | |||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Chrome | Edge | Firefox | Opera | Safari | Chrome Android | Firefox for Android | Opera Android | Safari on iOS | Samsung Internet | WebView Android | WebView on iOS | Bun | Deno | Node.js | |
zip |
153 |
153 |
148 |
137 |
preview |
153 |
148 |
Нет |
Нет |
Нет |
153 |
Нет |
1.4.0 |
Нет |
Нет |
См. также
- Polyfill для
Iterator.zipвcore-js - es-shims polyfill для
Iterator.zip IteratorIterator.zipKeyed()Iterator.from()Iterator.concat()
© 2005–2025 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Iterator/zip