UNPKG

@phosphor/algorithm

Version:

PhosphorJS - Algorithms and Iterators

545 lines (544 loc) 14.4 kB
"use strict"; /*----------------------------------------------------------------------------- | Copyright (c) 2014-2017, PhosphorJS Contributors | | Distributed under the terms of the BSD 3-Clause License. | | The full license is in the file LICENSE, distributed with this software. |----------------------------------------------------------------------------*/ Object.defineProperty(exports, "__esModule", { value: true }); /** * Create an iterator for an iterable object. * * @param object - The iterable or array-like object of interest. * * @returns A new iterator for the given object. * * #### Notes * This function allows iteration algorithms to operate on user-defined * iterable types and builtin array-like objects in a uniform fashion. */ function iter(object) { var it; if (typeof object.iter === 'function') { it = object.iter(); } else { it = new ArrayIterator(object); } return it; } exports.iter = iter; /** * Create an iterator for the keys in an object. * * @param object - The object of interest. * * @returns A new iterator for the keys in the given object. * * #### Complexity * Linear. * * #### Example * ```typescript * import { each, keys } from '@phosphor/algorithm'; * * let data = { one: 1, two: 2, three: 3 }; * * each(keys(data), key => { console.log(key); }); // 'one', 'two', 'three' * ``` */ function iterKeys(object) { return new KeyIterator(object); } exports.iterKeys = iterKeys; /** * Create an iterator for the values in an object. * * @param object - The object of interest. * * @returns A new iterator for the values in the given object. * * #### Complexity * Linear. * * #### Example * ```typescript * import { each, values } from '@phosphor/algorithm'; * * let data = { one: 1, two: 2, three: 3 }; * * each(values(data), value => { console.log(value); }); // 1, 2, 3 * ``` */ function iterValues(object) { return new ValueIterator(object); } exports.iterValues = iterValues; /** * Create an iterator for the items in an object. * * @param object - The object of interest. * * @returns A new iterator for the items in the given object. * * #### Complexity * Linear. * * #### Example * ```typescript * import { each, items } from '@phosphor/algorithm'; * * let data = { one: 1, two: 2, three: 3 }; * * each(items(data), value => { console.log(value); }); // ['one', 1], ['two', 2], ['three', 3] * ``` */ function iterItems(object) { return new ItemIterator(object); } exports.iterItems = iterItems; /** * Create an iterator for an iterator-like function. * * @param fn - A function which behaves like an iterator `next` method. * * @returns A new iterator for the given function. * * #### Notes * The returned iterator **cannot** be cloned. * * #### Example * ```typescript * import { each, iterFn } from '@phosphor/algorithm'; * * let it = iterFn((() => { * let i = 0; * return () => i > 3 ? undefined : i++; * })()); * * each(it, v => { console.log(v); }); // 0, 1, 2, 3 * ``` */ function iterFn(fn) { return new FnIterator(fn); } exports.iterFn = iterFn; /** * Invoke a function for each value in an iterable. * * @param object - The iterable or array-like object of interest. * * @param fn - The callback function to invoke for each value. * * #### Notes * Iteration can be terminated early by returning `false` from the * callback function. * * #### Complexity * Linear. * * #### Example * ```typescript * import { each } from '@phosphor/algorithm'; * * let data = [5, 7, 0, -2, 9]; * * each(data, value => { console.log(value); }); * ``` */ function each(object, fn) { var index = 0; var it = iter(object); var value; while ((value = it.next()) !== undefined) { if (fn(value, index++) === false) { return; } } } exports.each = each; /** * Test whether all values in an iterable satisfy a predicate. * * @param object - The iterable or array-like object of interest. * * @param fn - The predicate function to invoke for each value. * * @returns `true` if all values pass the test, `false` otherwise. * * #### Notes * Iteration terminates on the first `false` predicate result. * * #### Complexity * Linear. * * #### Example * ```typescript * import { every } from '@phosphor/algorithm'; * * let data = [5, 7, 1]; * * every(data, value => value % 2 === 0); // false * every(data, value => value % 2 === 1); // true * ``` */ function every(object, fn) { var index = 0; var it = iter(object); var value; while ((value = it.next()) !== undefined) { if (!fn(value, index++)) { return false; } } return true; } exports.every = every; /** * Test whether any value in an iterable satisfies a predicate. * * @param object - The iterable or array-like object of interest. * * @param fn - The predicate function to invoke for each value. * * @returns `true` if any value passes the test, `false` otherwise. * * #### Notes * Iteration terminates on the first `true` predicate result. * * #### Complexity * Linear. * * #### Example * ```typescript * import { some } from '@phosphor/algorithm'; * * let data = [5, 7, 1]; * * some(data, value => value === 7); // true * some(data, value => value === 3); // false * ``` */ function some(object, fn) { var index = 0; var it = iter(object); var value; while ((value = it.next()) !== undefined) { if (fn(value, index++)) { return true; } } return false; } exports.some = some; /** * Create an array from an iterable of values. * * @param object - The iterable or array-like object of interest. * * @returns A new array of values from the given object. * * #### Example * ```typescript * import { iter, toArray } from '@phosphor/algorithm'; * * let data = [1, 2, 3, 4, 5, 6]; * * let stream = iter(data); * * toArray(stream); // [1, 2, 3, 4, 5, 6]; * ``` */ function toArray(object) { var index = 0; var result = []; var it = iter(object); var value; while ((value = it.next()) !== undefined) { result[index++] = value; } return result; } exports.toArray = toArray; /** * Create an object from an iterable of key/value pairs. * * @param object - The iterable or array-like object of interest. * * @returns A new object mapping keys to values. * * #### Example * ```typescript * import { toObject } from '@phosphor/algorithm'; * * let data = [['one', 1], ['two', 2], ['three', 3]]; * * toObject(data); // { one: 1, two: 2, three: 3 } * ``` */ function toObject(object) { var it = iter(object); var pair; var result = {}; while ((pair = it.next()) !== undefined) { result[pair[0]] = pair[1]; } return result; } exports.toObject = toObject; /** * An iterator for an array-like object. * * #### Notes * This iterator can be used for any builtin JS array-like object. */ var ArrayIterator = /** @class */ (function () { /** * Construct a new array iterator. * * @param source - The array-like object of interest. */ function ArrayIterator(source) { this._index = 0; this._source = source; } /** * Get an iterator over the object's values. * * @returns An iterator which yields the object's values. */ ArrayIterator.prototype.iter = function () { return this; }; /** * Create an independent clone of the iterator. * * @returns A new independent clone of the iterator. */ ArrayIterator.prototype.clone = function () { var result = new ArrayIterator(this._source); result._index = this._index; return result; }; /** * Get the next value from the iterator. * * @returns The next value from the iterator, or `undefined`. */ ArrayIterator.prototype.next = function () { if (this._index >= this._source.length) { return undefined; } return this._source[this._index++]; }; return ArrayIterator; }()); exports.ArrayIterator = ArrayIterator; /** * An iterator for the keys in an object. * * #### Notes * This iterator can be used for any JS object. */ var KeyIterator = /** @class */ (function () { /** * Construct a new key iterator. * * @param source - The object of interest. * * @param keys - The keys to iterate, if known. */ function KeyIterator(source, keys) { if (keys === void 0) { keys = Object.keys(source); } this._index = 0; this._source = source; this._keys = keys; } /** * Get an iterator over the object's values. * * @returns An iterator which yields the object's values. */ KeyIterator.prototype.iter = function () { return this; }; /** * Create an independent clone of the iterator. * * @returns A new independent clone of the iterator. */ KeyIterator.prototype.clone = function () { var result = new KeyIterator(this._source, this._keys); result._index = this._index; return result; }; /** * Get the next value from the iterator. * * @returns The next value from the iterator, or `undefined`. */ KeyIterator.prototype.next = function () { if (this._index >= this._keys.length) { return undefined; } var key = this._keys[this._index++]; if (key in this._source) { return key; } return this.next(); }; return KeyIterator; }()); exports.KeyIterator = KeyIterator; /** * An iterator for the values in an object. * * #### Notes * This iterator can be used for any JS object. */ var ValueIterator = /** @class */ (function () { /** * Construct a new value iterator. * * @param source - The object of interest. * * @param keys - The keys to iterate, if known. */ function ValueIterator(source, keys) { if (keys === void 0) { keys = Object.keys(source); } this._index = 0; this._source = source; this._keys = keys; } /** * Get an iterator over the object's values. * * @returns An iterator which yields the object's values. */ ValueIterator.prototype.iter = function () { return this; }; /** * Create an independent clone of the iterator. * * @returns A new independent clone of the iterator. */ ValueIterator.prototype.clone = function () { var result = new ValueIterator(this._source, this._keys); result._index = this._index; return result; }; /** * Get the next value from the iterator. * * @returns The next value from the iterator, or `undefined`. */ ValueIterator.prototype.next = function () { if (this._index >= this._keys.length) { return undefined; } var key = this._keys[this._index++]; if (key in this._source) { return this._source[key]; } return this.next(); }; return ValueIterator; }()); exports.ValueIterator = ValueIterator; /** * An iterator for the items in an object. * * #### Notes * This iterator can be used for any JS object. */ var ItemIterator = /** @class */ (function () { /** * Construct a new item iterator. * * @param source - The object of interest. * * @param keys - The keys to iterate, if known. */ function ItemIterator(source, keys) { if (keys === void 0) { keys = Object.keys(source); } this._index = 0; this._source = source; this._keys = keys; } /** * Get an iterator over the object's values. * * @returns An iterator which yields the object's values. */ ItemIterator.prototype.iter = function () { return this; }; /** * Create an independent clone of the iterator. * * @returns A new independent clone of the iterator. */ ItemIterator.prototype.clone = function () { var result = new ItemIterator(this._source, this._keys); result._index = this._index; return result; }; /** * Get the next value from the iterator. * * @returns The next value from the iterator, or `undefined`. */ ItemIterator.prototype.next = function () { if (this._index >= this._keys.length) { return undefined; } var key = this._keys[this._index++]; if (key in this._source) { return [key, this._source[key]]; } return this.next(); }; return ItemIterator; }()); exports.ItemIterator = ItemIterator; /** * An iterator for an iterator-like function. */ var FnIterator = /** @class */ (function () { /** * Construct a new function iterator. * * @param fn - The iterator-like function of interest. */ function FnIterator(fn) { this._fn = fn; } /** * Get an iterator over the object's values. * * @returns An iterator which yields the object's values. */ FnIterator.prototype.iter = function () { return this; }; /** * Create an independent clone of the iterator. * * @returns A new independent clone of the iterator. */ FnIterator.prototype.clone = function () { throw new Error('An `FnIterator` cannot be cloned.'); }; /** * Get the next value from the iterator. * * @returns The next value from the iterator, or `undefined`. */ FnIterator.prototype.next = function () { return this._fn.call(undefined); }; return FnIterator; }()); exports.FnIterator = FnIterator;