Skip to content

Commit

Permalink
Reimplement filter<T>() with native interators
Browse files Browse the repository at this point in the history
  • Loading branch information
afshin committed Aug 11, 2022
1 parent 2a43121 commit 349ac0c
Showing 1 changed file with 10 additions and 64 deletions.
74 changes: 10 additions & 64 deletions packages/algorithm/src/filter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,89 +7,35 @@
|
| The full license is in the file LICENSE, distributed with this software.
|----------------------------------------------------------------------------*/
import { IIterator, iter, IterableOrArrayLike } from './iter';

/**
* Filter an iterable for values which pass a test.
*
* @param object - The iterable or array-like object of interest.
* @param object - The iterable object of interest.
*
* @param fn - The predicate function to invoke for each value.
*
* @returns An iterator which yields the values which pass the test.
*
* #### Example
* ```typescript
* import { filter, toArray } from '@lumino/algorithm';
* import { filter } from '@lumino/algorithm';
*
* let data = [1, 2, 3, 4, 5, 6];
*
* let stream = filter(data, value => value % 2 === 0);
*
* toArray(stream); // [2, 4, 6]
* Array.from(stream); // [2, 4, 6]
* ```
*/
export function filter<T>(
object: IterableOrArrayLike<T>,
export function* filter<T>(
object: Iterable<T>,
fn: (value: T, index: number) => boolean
): IIterator<T> {
return new FilterIterator<T>(iter(object), fn);
}

/**
* An iterator which yields values which pass a test.
*/
export class FilterIterator<T> implements IIterator<T> {
/**
* Construct a new filter iterator.
*
* @param source - The iterator of values of interest.
*
* @param fn - The predicate function to invoke for each value.
*/
constructor(source: IIterator<T>, fn: (value: T, index: number) => boolean) {
this._source = source;
this._fn = fn;
}

/**
* Get an iterator over the object's values.
*
* @returns An iterator which yields the object's values.
*/
iter(): IIterator<T> {
return this;
}

/**
* Create an independent clone of the iterator.
*
* @returns A new independent clone of the iterator.
*/
clone(): IIterator<T> {
let result = new FilterIterator<T>(this._source.clone(), this._fn);
result._index = this._index;
return result;
}

/**
* Get the next value from the iterator.
*
* @returns The next value from the iterator, or `undefined`.
*/
next(): T | undefined {
let fn = this._fn;
let it = this._source;
let value: T | undefined;
while ((value = it.next()) !== undefined) {
if (fn(value, this._index++)) {
return value;
}
) {
const it = object[Symbol.iterator]();
for (let index = 0, item = it.next(); !item.done; item = it.next()) {
if (fn(item.value, index++)) {
yield item.value;
}
return undefined;
}

private _index = 0;
private _source: IIterator<T>;
private _fn: (value: T, index: number) => boolean;
}

0 comments on commit 349ac0c

Please sign in to comment.