UNPKG

2.62 kBPlain TextView Raw
1// Copyright (c) Jupyter Development Team.
2// Distributed under the terms of the Modified BSD License.
3/*-----------------------------------------------------------------------------
4| Copyright (c) 2014-2017, PhosphorJS Contributors
5|
6| Distributed under the terms of the BSD 3-Clause License.
7|
8| The full license is in the file LICENSE, distributed with this software.
9|----------------------------------------------------------------------------*/
10import { IIterator, iter, IterableOrArrayLike } from './iter';
11
12/**
13 * Chain together several iterables.
14 *
15 * @param objects - The iterable or array-like objects of interest.
16 *
17 * @returns An iterator which yields the values of the iterables
18 * in the order in which they are supplied.
19 *
20 * #### Example
21 * ```typescript
22 * import { chain, toArray } from '@lumino/algorithm';
23 *
24 * let data1 = [1, 2, 3];
25 * let data2 = [4, 5, 6];
26 *
27 * let stream = chain(data1, data2);
28 *
29 * toArray(stream); // [1, 2, 3, 4, 5, 6]
30 * ```
31 */
32export function chain<T>(...objects: IterableOrArrayLike<T>[]): IIterator<T> {
33 return new ChainIterator<T>(iter(objects.map(iter)));
34}
35
36/**
37 * An iterator which chains together several iterators.
38 */
39export class ChainIterator<T> implements IIterator<T> {
40 /**
41 * Construct a new chain iterator.
42 *
43 * @param source - The iterator of iterators of interest.
44 */
45 constructor(source: IIterator<IIterator<T>>) {
46 this._source = source;
47 this._active = undefined;
48 }
49
50 /**
51 * Get an iterator over the object's values.
52 *
53 * @returns An iterator which yields the object's values.
54 */
55 iter(): IIterator<T> {
56 return this;
57 }
58
59 /**
60 * Create an independent clone of the iterator.
61 *
62 * @returns A new independent clone of the iterator.
63 */
64 clone(): IIterator<T> {
65 let result = new ChainIterator<T>(this._source.clone());
66 result._active = this._active && this._active.clone();
67 result._cloned = true;
68 this._cloned = true;
69 return result;
70 }
71
72 /**
73 * Get the next value from the iterator.
74 *
75 * @returns The next value from the iterator, or `undefined`.
76 */
77 next(): T | undefined {
78 if (this._active === undefined) {
79 let active = this._source.next();
80 if (active === undefined) {
81 return undefined;
82 }
83 this._active = this._cloned ? active.clone() : active;
84 }
85 let value = this._active.next();
86 if (value !== undefined) {
87 return value;
88 }
89 this._active = undefined;
90 return this.next();
91 }
92
93 private _source: IIterator<IIterator<T>>;
94 private _active: IIterator<T> | undefined;
95 private _cloned = false;
96}