@@ -72,13 +72,11 @@ export function contains<T>(iterable: AnyIterable<T>, needle: T) {
72
72
/**
73
73
* Returns an iterable of enumeration pairs.
74
74
*/
75
- export async function * enumerate < T > (
75
+ export function enumerate < T > (
76
76
iterable : AnyIterable < T > ,
77
77
offset = 0
78
78
) : AsyncIterable < [ number , T ] > {
79
- let index = offset ;
80
-
81
- for await ( const value of iterable ) yield [ index ++ , value ] ;
79
+ return zip ( range ( offset ) , iterable ) ;
82
80
}
83
81
84
82
/**
@@ -188,8 +186,9 @@ export async function* cycle<T>(iterable: AnyIterable<T>): AsyncIterable<T> {
188
186
/**
189
187
* Make an iterator that repeats `value` over and over again.
190
188
*/
191
- export async function * repeat < T > ( value : T ) : AsyncIterable < T > {
192
- while ( true ) yield value ;
189
+ export async function * repeat < T > ( value : T , times ?: number ) : AsyncIterable < T > {
190
+ if ( times === undefined ) while ( true ) yield value ;
191
+ for ( let i = 0 ; i < times ; i ++ ) yield value ;
193
192
}
194
193
195
194
/**
@@ -642,3 +641,37 @@ export async function sum(
642
641
) : Promise < number > {
643
642
return reduce ( iterable , ( x , y ) => x + y , start ) ;
644
643
}
644
+
645
+ /**
646
+ * Recursively produce all produces of a list of iterators.
647
+ */
648
+ async function * _product < T > (
649
+ pools : AnyIterator < T | typeof SENTINEL > [ ] ,
650
+ buffer : T [ ] = [ ]
651
+ ) : AsyncIterable < T [ ] > {
652
+ if ( pools . length === 0 ) {
653
+ yield buffer . slice ( ) ;
654
+ return ;
655
+ }
656
+
657
+ const [ pool , ...others ] = pools ;
658
+
659
+ while ( true ) {
660
+ const item = await pool . next ( ) ;
661
+ if ( item . value === SENTINEL ) break ;
662
+ buffer . push ( item . value ) ;
663
+ yield * _product ( others , buffer ) ;
664
+ buffer . pop ( ) ;
665
+ }
666
+ }
667
+
668
+ /**
669
+ * Cartesian product of input iterables.
670
+ */
671
+ export async function * product < T extends any [ ] > (
672
+ ...iterables : AnyTupleIterable < T >
673
+ ) : AsyncIterable < T > {
674
+ const pools = iterables . map ( x => iter ( cycle ( chain ( x , repeat ( SENTINEL , 1 ) ) ) ) ) ;
675
+
676
+ yield * _product ( pools ) as AsyncIterable < T > ;
677
+ }
0 commit comments