UNPKG

2.56 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 * Filter an iterable for values which pass a test.
14 *
15 * @param object - The iterable or array-like object of interest.
16 *
17 * @param fn - The predicate function to invoke for each value.
18 *
19 * @returns An iterator which yields the values which pass the test.
20 *
21 * #### Example
22 * ```typescript
23 * import { filter, toArray } from '@lumino/algorithm';
24 *
25 * let data = [1, 2, 3, 4, 5, 6];
26 *
27 * let stream = filter(data, value => value % 2 === 0);
28 *
29 * toArray(stream); // [2, 4, 6]
30 * ```
31 */
32export function filter<T>(
33 object: IterableOrArrayLike<T>,
34 fn: (value: T, index: number) => boolean
35): IIterator<T> {
36 return new FilterIterator<T>(iter(object), fn);
37}
38
39/**
40 * An iterator which yields values which pass a test.
41 */
42export class FilterIterator<T> implements IIterator<T> {
43 /**
44 * Construct a new filter iterator.
45 *
46 * @param source - The iterator of values of interest.
47 *
48 * @param fn - The predicate function to invoke for each value.
49 */
50 constructor(source: IIterator<T>, fn: (value: T, index: number) => boolean) {
51 this._source = source;
52 this._fn = fn;
53 }
54
55 /**
56 * Get an iterator over the object's values.
57 *
58 * @returns An iterator which yields the object's values.
59 */
60 iter(): IIterator<T> {
61 return this;
62 }
63
64 /**
65 * Create an independent clone of the iterator.
66 *
67 * @returns A new independent clone of the iterator.
68 */
69 clone(): IIterator<T> {
70 let result = new FilterIterator<T>(this._source.clone(), this._fn);
71 result._index = this._index;
72 return result;
73 }
74
75 /**
76 * Get the next value from the iterator.
77 *
78 * @returns The next value from the iterator, or `undefined`.
79 */
80 next(): T | undefined {
81 let fn = this._fn;
82 let it = this._source;
83 let value: T | undefined;
84 while ((value = it.next()) !== undefined) {
85 if (fn(value, this._index++)) {
86 return value;
87 }
88 }
89 return undefined;
90 }
91
92 private _index = 0;
93 private _source: IIterator<T>;
94 private _fn: (value: T, index: number) => boolean;
95}