-
Notifications
You must be signed in to change notification settings - Fork 3
/
roundrobin.js
40 lines (32 loc) · 1003 Bytes
/
roundrobin.js
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
import {iter, len, cycle, map, slice} from '../index.js';
/**
* Yields the first item of the first input iterable, then the first item of
* the second input iterable, etc., until the last input iterable. Then start
* again with the second item of the first input iterable, etc. If one of the
* input iterable is exhausted, it is removed from the list of input iterables
* and the algorithm continues until all input iterables have been exhausted.
*
* @example
* // returns ['A','D','E','B','F','C]
* list( roundrobin(['ABC', 'D', 'EF']) )
*
* @param {Iterable[]} iterables - The input iterables.
* @returns {Iterator}
*
*/
export function* roundrobin(iterables) {
let pending = len(iterables);
let iterators = cycle(map(iter, iterables));
while (pending) {
while (true) {
const iterator = iterators.next().value;
const it = iterator.next();
if (it.done) {
break;
}
yield it.value;
}
--pending;
iterators = cycle(slice(iterators, 0, pending, 1));
}
}