Skip to content

Commit 3b6a71f

Browse files
committed
docs(zip): refine signature and docs
1 parent c42b44d commit 3b6a71f

File tree

2 files changed

+57
-19
lines changed

2 files changed

+57
-19
lines changed

async/zip.ts

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,58 @@
11
/**
22
* Zips multiple iterables into a single iterable.
33
*
4+
* The resulting iterable will yield arrays of elements from the input iterables.
5+
* The first array will contain the first element of each input iterable, the second array will contain the second element of each input iterable, and so on.
6+
*
7+
* If the input iterables have different lengths, the resulting iterable will stop when the shortest input iterable is exhausted.
8+
* The remaining elements from the longer input iterables will be ignored.
9+
*
10+
* Use {@linkcode https://jsr.io/@core/iterutil/async/chain chain} to chain iterables.
11+
* Use {@linkcode https://jsr.io/@core/iterutil/async/enumerate enumerate} to zip with indices.
12+
* Use {@linkcode https://jsr.io/@core/iterutil/zip zip} to zip iterables synchronously.
13+
*
414
* @param iterables The iterables to zip.
515
* @returns The zipped iterable.
616
*
717
* @example
818
* ```ts
919
* import { zip } from "@core/iterutil/async/zip";
1020
*
11-
* const iter = zip([1, 2, 3], ["a", "b", "c"]);
12-
* console.log(await Array.fromAsync(iter)); // [[1, "a"], [2, "b"], [3, "c"]]
21+
* const iter = zip(
22+
* [1, 2, 3],
23+
* ["a", "b", "c"],
24+
* [true, false, true],
25+
* );
26+
* console.log(await Array.fromAsync(iter)); // [[1, "a", true], [2, "b", false], [3, "c", true]]
1327
* ```
1428
*/
1529
export async function* zip<
16-
U extends (Iterable<unknown> | AsyncIterable<unknown>)[],
30+
U extends readonly [
31+
Iterable<unknown> | AsyncIterable<unknown>,
32+
Iterable<unknown> | AsyncIterable<unknown>,
33+
...(Iterable<unknown> | AsyncIterable<unknown>)[],
34+
],
1735
>(
1836
...iterables: U
1937
): AsyncIterable<Zip<U>> {
20-
const its = iterables.map((iterable) =>
21-
Symbol.iterator in iterable
22-
? iterable[Symbol.iterator]()
23-
: iterable[Symbol.asyncIterator]()
38+
const iterators = iterables.map((it) =>
39+
Symbol.iterator in it ? it[Symbol.iterator]() : it[Symbol.asyncIterator]()
2440
);
2541
while (true) {
26-
const rs = await Promise.all(its.map((it) => it.next()));
27-
if (rs.find(({ done }) => !!done)) {
42+
const results = await Promise.all(iterators.map((it) => it.next()));
43+
if (results.find(({ done }) => !!done)) {
2844
break;
2945
}
30-
yield rs.map(({ value }) => value) as Zip<U>;
46+
yield results.map(({ value }) => value) as Zip<U>;
3147
}
3248
}
3349

3450
/**
3551
* @internal
3652
*/
37-
export type Zip<T extends (Iterable<unknown> | AsyncIterable<unknown>)[]> = {
53+
export type Zip<
54+
T extends readonly (Iterable<unknown> | AsyncIterable<unknown>)[],
55+
> = {
3856
[P in keyof T]: T[P] extends Iterable<infer U> ? U
3957
: T[P] extends AsyncIterable<infer U> ? U
4058
: never;

zip.ts

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,53 @@
11
/**
22
* Zips multiple iterables into a single iterable.
33
*
4+
* The resulting iterable will yield arrays of elements from the input iterables.
5+
* The first array will contain the first element of each input iterable, the second array will contain the second element of each input iterable, and so on.
6+
*
7+
* If the input iterables have different lengths, the resulting iterable will stop when the shortest input iterable is exhausted.
8+
* The remaining elements from the longer input iterables will be ignored.
9+
*
10+
* Use {@linkcode https://jsr.io/@core/iterutil/chain chain} to chain iterables.
11+
* Use {@linkcode https://jsr.io/@core/iterutil/enumerate enumerate} to zip with indices.
12+
* Use {@linkcode https://jsr.io/@core/iterutil/async/zip async zip} to zip asynchronously.;w
13+
*
414
* @param iterables The iterables to zip.
515
* @returns The zipped iterable.
616
*
717
* @example
818
* ```ts
919
* import { zip } from "@core/iterutil/zip";
1020
*
11-
* const iter = zip([1, 2, 3], ["a", "b", "c"]);
12-
* console.log(Array.from(iter)); // [[1, "a"], [2, "b"], [3, "c"]]
21+
* const iter = zip(
22+
* [1, 2, 3],
23+
* ["a", "b", "c"],
24+
* [true, false, true],
25+
* );
26+
* console.log(Array.from(iter)); // [[1, "a", true], [2, "b", false], [3, "c", true]]
1327
* ```
1428
*/
15-
export function* zip<U extends Iterable<unknown>[]>(
29+
export function* zip<
30+
U extends readonly [
31+
Iterable<unknown>,
32+
Iterable<unknown>,
33+
...Iterable<unknown>[],
34+
],
35+
>(
1636
...iterables: U
1737
): Iterable<Zip<U>> {
18-
const its = iterables.map((iterable) => iterable[Symbol.iterator]());
38+
const iterators = iterables.map((it) => it[Symbol.iterator]());
1939
while (true) {
20-
const rs = its.map((it) => it.next());
21-
if (rs.find(({ done }) => !!done)) {
40+
const results = iterators.map((it) => it.next());
41+
if (results.find(({ done }) => !!done)) {
2242
break;
2343
}
24-
yield rs.map(({ value }) => value) as Zip<U>;
44+
yield results.map(({ value }) => value) as Zip<U>;
2545
}
2646
}
2747

2848
/**
2949
* @internal
3050
*/
31-
export type Zip<T extends Iterable<unknown>[]> = {
51+
export type Zip<T extends readonly Iterable<unknown>[]> = {
3252
[P in keyof T]: T[P] extends Iterable<infer U> ? U : never;
3353
};

0 commit comments

Comments
 (0)