UNPKG

trie-typed

Version:
244 lines (243 loc) 7.98 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.IterableElementBase = void 0; /** * Base class that makes a data structure iterable and provides common * element-wise utilities (e.g., map/filter/reduce/find). * * @template E The public element type yielded by the structure. * @template R The underlying "raw" element type used internally or by converters. * * @remarks * This class implements the JavaScript iteration protocol (via `Symbol.iterator`) * and offers array-like helpers with predictable time/space complexity. */ class IterableElementBase { /** * Create a new iterable base. * * @param options Optional behavior overrides. When provided, a `toElementFn` * is used to convert a raw element (`R`) into a public element (`E`). * * @remarks * Time O(1), Space O(1). */ constructor(options) { if (options) { const { toElementFn } = options; if (typeof toElementFn === 'function') this._toElementFn = toElementFn; else if (toElementFn) throw new TypeError('toElementFn must be a function type'); } } /** * Exposes the current `toElementFn`, if configured. * * @returns The converter function or `undefined` when not set. * @remarks * Time O(1), Space O(1). */ get toElementFn() { return this._toElementFn; } /** * Returns an iterator over the structure's elements. * * @param args Optional iterator arguments forwarded to the internal iterator. * @returns An `IterableIterator<E>` that yields the elements in traversal order. * * @remarks * Producing the iterator is O(1); consuming the entire iterator is Time O(n) with O(1) extra space. */ *[Symbol.iterator](...args) { yield* this._getIterator(...args); } /** * Returns an iterator over the values (alias of the default iterator). * * @returns An `IterableIterator<E>` over all elements. * @remarks * Creating the iterator is O(1); full iteration is Time O(n), Space O(1). */ *values() { for (const item of this) yield item; } /** * Tests whether all elements satisfy the predicate. * * @template TReturn * @param predicate Function invoked for each element with signature `(value, index, self)`. * @param thisArg Optional `this` binding for the predicate. * @returns `true` if every element passes; otherwise `false`. * * @remarks * Time O(n) in the worst case; may exit early when the first failure is found. Space O(1). */ every(predicate, thisArg) { let index = 0; for (const item of this) { if (thisArg === undefined) { if (!predicate(item, index++, this)) return false; } else { const fn = predicate; if (!fn.call(thisArg, item, index++, this)) return false; } } return true; } /** * Tests whether at least one element satisfies the predicate. * * @param predicate Function invoked for each element with signature `(value, index, self)`. * @param thisArg Optional `this` binding for the predicate. * @returns `true` if any element passes; otherwise `false`. * * @remarks * Time O(n) in the worst case; may exit early on first success. Space O(1). */ some(predicate, thisArg) { let index = 0; for (const item of this) { if (thisArg === undefined) { if (predicate(item, index++, this)) return true; } else { const fn = predicate; if (fn.call(thisArg, item, index++, this)) return true; } } return false; } /** * Invokes a callback for each element in iteration order. * * @param callbackfn Function invoked per element with signature `(value, index, self)`. * @param thisArg Optional `this` binding for the callback. * @returns `void`. * * @remarks * Time O(n), Space O(1). */ forEach(callbackfn, thisArg) { let index = 0; for (const item of this) { if (thisArg === undefined) { callbackfn(item, index++, this); } else { const fn = callbackfn; fn.call(thisArg, item, index++, this); } } } // Implementation signature find(predicate, thisArg) { let index = 0; for (const item of this) { if (thisArg === undefined) { if (predicate(item, index++, this)) return item; } else { const fn = predicate; if (fn.call(thisArg, item, index++, this)) return item; } } return; } /** * Checks whether a strictly-equal element exists in the structure. * * @param element The element to test with `===` equality. * @returns `true` if an equal element is found; otherwise `false`. * * @remarks * Time O(n) in the worst case. Space O(1). */ has(element) { for (const ele of this) if (ele === element) return true; return false; } /** * Reduces all elements to a single accumulated value. * * @overload * @param callbackfn Reducer of signature `(acc, value, index, self) => nextAcc`. The first element is used as the initial accumulator. * @returns The final accumulated value typed as `E`. * * @overload * @param callbackfn Reducer of signature `(acc, value, index, self) => nextAcc`. * @param initialValue The initial accumulator value of type `E`. * @returns The final accumulated value typed as `E`. * * @overload * @template U The accumulator type when it differs from `E`. * @param callbackfn Reducer of signature `(acc: U, value, index, self) => U`. * @param initialValue The initial accumulator value of type `U`. * @returns The final accumulated value typed as `U`. * * @remarks * Time O(n), Space O(1). Throws if called on an empty structure without `initialValue`. */ reduce(callbackfn, initialValue) { let index = 0; const iter = this[Symbol.iterator](); let acc; if (arguments.length >= 2) { acc = initialValue; } else { const first = iter.next(); if (first.done) throw new TypeError('Reduce of empty structure with no initial value'); acc = first.value; index = 1; } for (const value of iter) { acc = callbackfn(acc, value, index++, this); } return acc; } /** * Materializes the elements into a new array. * * @returns A shallow array copy of the iteration order. * @remarks * Time O(n), Space O(n). */ toArray() { return [...this]; } /** * Returns a representation of the structure suitable for quick visualization. * Defaults to an array of elements; subclasses may override to provide richer visuals. * * @returns A visual representation (array by default). * @remarks * Time O(n), Space O(n). */ toVisual() { return [...this]; } /** * Prints `toVisual()` to the console. Intended for quick debugging. * * @returns `void`. * @remarks * Time O(n) due to materialization, Space O(n) for the intermediate representation. */ print() { console.log(this.toVisual()); } } exports.IterableElementBase = IterableElementBase;