import { OmniSequence, OutDestination } from "../../types/sequence/omni-sequence" import { Pipe } from "../../types/sequence/pipe" import { Span } from "../../types/sequence/span" import { Comparator, Dictionary, PairPredicate, Positional, Predicate, Sequence, Transform, Falsy } from "../../types/types" import { is } from "../static/equality" /** * Pipe used when a pipe is only temporarily needed. */ const recycledPipe = new Pipe([]) /** * Span used when a span is only temporarily needed. */ const recycledSpan = new Span([], 0, 0) /** * Allocates a new pipe over a **sequence**. */ function getPipe(sequence: Sequence): OmniSequence { return new Pipe(sequence) } /** * Allocates a new span over a positional **sequence**. */ function getSpan(sequence: Positional): OmniSequence { return new Span(sequence) } /** * Re-seats the module's recycled pipe onto a **sequence**. */ function resetPipe(sequence: Sequence): OmniSequence { (recycledPipe as any)._seat(sequence) return recycledPipe } /** * Re-seats the module's recycled span onto a positional **sequence**. */ function resetSpan(sequence: Positional): OmniSequence { (recycledSpan as any)._seat(sequence) return recycledSpan } /** * Returns true if the **sequence** can be considered positional and a span can be created from it. */ function isPositional(sequence: Sequence): boolean { return Array.isArray(sequence) || typeof sequence === "string" } /** * Returns a new span over the **sequence** if the input **sequence** is positional and a new pipe otherwise. */ function getOmniSequence(sequence: Sequence): OmniSequence { if (sequence instanceof Span || sequence instanceof Pipe) { return sequence } return isPositional(sequence) ? getSpan(sequence as Positional) : getPipe(sequence) } /** * Returns a recycled span over the **sequence** if the input **sequence** is positional and a recycled pipe otherwise. */ function resetOmniSequence(sequence: Sequence): OmniSequence { if (sequence instanceof Span || sequence instanceof Pipe) { return sequence } return isPositional(sequence) ? resetSpan(sequence as Positional) : resetPipe(sequence) } /** * Static version of [[OmniSequence.solid]] that works on any sequence. */ export function solid(sequence: Sequence): OmniSequence { return resetOmniSequence(sequence).solid() } /** * Static version of [[OmniSequence.all]] that works on any sequence. */ export function all(sequence: Sequence, predicate: Predicate): boolean { return resetOmniSequence(sequence).all(predicate) } /** * Static version of [[OmniSequence.as]] that works on any sequence. */ export function as(sequence: Sequence): OmniSequence { return getOmniSequence(sequence).as() } /** * Static version of [[OmniSequence.concat]] that works on any sequence. */ export function concat(sequence: Sequence, other: Sequence): OmniSequence { return getOmniSequence(sequence).concat(other) } /** * Static version of [[OmniSequence.append]] that works on any sequence. */ export function append(sequence: Sequence, ...elements: T[]): OmniSequence { return getOmniSequence(sequence).append(...elements) } /** * Static version of [[OmniSequence.associate]] that works on any sequence. */ export function associate(sequence: Sequence, transform: Transform): OmniSequence<[K, T]> { return getOmniSequence(sequence).associate(transform) } /** * Static version of [[OmniSequence.at]] that works on any sequence. */ export function at(sequence: Sequence, index: number): T { return resetOmniSequence(sequence).at(index) } /** * Static version of [[OmniSequence.cleave]] that works on any sequence. */ export function cleave(sequence: Sequence, index: number): [T[], T[]] { return resetOmniSequence(sequence).cleave(index) } /** * Static version of [[OmniSequence.count]] that works on any sequence. */ export function count(sequence: Sequence): number export function count(sequence: Sequence, predicate: Predicate): number export function count(sequence: Sequence, predicate?: Predicate): number { return resetOmniSequence(sequence).count(predicate as Predicate) } /** * Static version of [[OmniSequence.cut]] that works on any sequence. */ export function cut(sequence: Sequence, start: number): OmniSequence export function cut(sequence: Sequence, start: number, count: number): OmniSequence export function cut(sequence: Sequence, start: number, count?: number): OmniSequence { return getOmniSequence(sequence).cut(start, count as number) } /** * Static version of [[OmniSequence.chunk]] that works on any sequence. */ export function chunk(sequence: Sequence, count: number): OmniSequence { return getOmniSequence(sequence).chunk(count) } /** * Static version of [[OmniSequence.difference]] that works on any sequence. */ export function difference(sequence: Sequence, other: Sequence): OmniSequence export function difference(sequence: Sequence, other: Sequence, transform: Transform): OmniSequence export function difference(sequence: Sequence, other: Sequence, transform?: Transform): OmniSequence { return getOmniSequence(sequence).difference(other, transform as Transform) } /** * Static version of [[OmniSequence.done]] that works on any sequence. */ export function done(sequence: Sequence): T[] { return resetOmniSequence(sequence).done() } /** * Static version of [[OmniSequence.drop]] that works on any sequence. */ export function drop(sequence: Sequence): OmniSequence export function drop(sequence: Sequence, count: number): OmniSequence export function drop(sequence: Sequence, predicate: Predicate): OmniSequence export function drop(sequence: Sequence, argument?: number | Predicate): OmniSequence { return getOmniSequence(sequence).drop(argument as any) } /** * Static version of [[OmniSequence.dropLast]] that works on any sequence. */ export function dropLast(sequence: Sequence): OmniSequence export function dropLast(sequence: Sequence, count: number): OmniSequence export function dropLast(sequence: Sequence, predicate: Predicate): OmniSequence export function dropLast(sequence: Sequence, argument?: number | Predicate): OmniSequence { return getOmniSequence(sequence).dropLast(argument as any) } /** * Static version of [[OmniSequence.each]] that works on any sequence. */ export function each(sequence: Sequence, action: (element: T, index: number, end: () => void) => void): OmniSequence { return getOmniSequence(sequence).each(action) } /** * Static version of [[OmniSequence.endsWith]] that works on any sequence. */ export function endsWith(sequence: Sequence, suffix: Positional): boolean export function endsWith(sequence: Sequence, suffix: Positional, equals: (value: T, other: T) => boolean): boolean export function endsWith(sequence: Sequence, suffix: Positional, equals: (value: T, other: T) => boolean = is): boolean { return resetOmniSequence(sequence).endsWith(suffix, equals) } /** * Static version of [[OmniSequence.entries]] that works on any sequence. */ export function entries(sequence: Sequence): OmniSequence<[number, T]> { return getOmniSequence(sequence).entries() } /** * Static version of [[OmniSequence.entriesReversed]] that works on any sequence. */ export function entriesReversed(sequence: Sequence): OmniSequence<[number, T]> { return getOmniSequence(sequence).entriesReversed() } /** * Static version of [[OmniSequence.filter]] that works on any sequence. */ export function filter(sequence: Sequence): OmniSequence export function filter(sequence: Sequence, predicate: Predicate): OmniSequence export function filter(sequence: Sequence, predicate?: Predicate): OmniSequence { return getOmniSequence(sequence).filter(predicate as Predicate) } /** * Static version of [[OmniSequence.find]] that works on any sequence. */ export function find(sequence: Sequence, predicate: Predicate): T | null export function find(sequence: Sequence, predicate: Predicate, instead: O): T | O export function find(sequence: Sequence, predicate: Predicate, instead?: O): T | O { return resetOmniSequence(sequence).find(predicate, instead) as T | O } /** * Static version of [[OmniSequence.findLast]] that works on any sequence. */ export function findLast(sequence: Sequence, predicate: Predicate): T export function findLast(sequence: Sequence, predicate: Predicate, instead: O): T | O export function findLast(sequence: Sequence, predicate: Predicate, instead?: O): T | O { return resetOmniSequence(sequence).findLast(predicate, instead) as T | O } /** * Static version of [[OmniSequence.first]] that works on any sequence. */ export function first(pair: [L, R]): L export function first(sequence: Sequence): T export function first(sequence: Sequence, instead: O): T | O export function first(sequence: Sequence, instead?: O): T | O { return resetOmniSequence(sequence).first(instead) as T | O } /** * Static version of [[OmniSequence.flat]] that works on any sequence. */ export function flat(sequence: Sequence>): OmniSequence { return getOmniSequence(sequence).flat() } /** * Static version of [[OmniSequence.fold]] that works on any sequence. */ export function fold(sequence: Sequence, initial: R, reducer: (accumulator: R, current: T) => R): R { return resetOmniSequence(sequence).fold(initial, reducer) } /** * Static version of [[OmniSequence.index]] that works on any sequence. */ export function index(sequence: Sequence, predicate: Predicate): number { return resetOmniSequence(sequence).index(predicate) } /** * Static version of [[OmniSequence.indices]] that works on any sequence. */ export function indices(sequence: Sequence): OmniSequence export function indices(sequence: Sequence, predicate: Predicate): OmniSequence export function indices(sequence: Sequence, predicate?: Predicate): OmniSequence { return getOmniSequence(sequence).indices(predicate as Predicate) } /** * Static version of [[OmniSequence.indicesReversed]] that works on any sequence. */ export function indicesReversed(sequence: Sequence): OmniSequence export function indicesReversed(sequence: Sequence, predicate: Predicate): OmniSequence export function indicesReversed(sequence: Sequence, predicate?: Predicate): OmniSequence { return getOmniSequence(sequence).indicesReversed(predicate as Predicate) } /** * Static version of [[OmniSequence.inject]] that works on any sequence. */ export function inject(sequence: Sequence, index: number, elements: Sequence): OmniSequence { return getOmniSequence(sequence).inject(index, elements) } /** * Static version of [[OmniSequence.intersect]] that works on any sequence. */ export function intersect(sequence: Sequence, other: Sequence): OmniSequence export function intersect(sequence: Sequence, other: Sequence, transform: Transform): OmniSequence export function intersect(sequence: Sequence, other: Sequence, transform?: Transform): OmniSequence { return getOmniSequence(sequence).intersect(other, transform as Transform) } /** * Static version of [[OmniSequence.insert]] that works on any sequence. */ export function insert(sequence: Sequence, index: number, ...elements: T[]): OmniSequence { return getOmniSequence(sequence).insert(index, ...elements) } /** * Static version of [[OmniSequence.invert]] that works on any sequence. */ export function invert(sequence: Sequence<[K, V]>): OmniSequence<[V, K]> { return getOmniSequence(sequence).invert() } /** * Static version of [[OmniSequence.join]] that works on any sequence. */ export function join(sequence: Sequence): string export function join(sequence: Sequence, separator: string): string export function join(sequence: Sequence, separator: string = ""): string { return resetOmniSequence(sequence).join(separator) } /** * Static version of [[OmniSequence.last]] that works on any sequence. */ export function last(pair: [L, R]): R export function last(sequence: Sequence): T export function last(sequence: Sequence, instead: O): T | O export function last(sequence: Sequence, instead?: O): T | O { return resetOmniSequence(sequence).last(instead) as T | O } /** * Static version of [[OmniSequence.lastIndex]] that works on any sequence. */ export function lastIndex(sequence: Sequence): number export function lastIndex(sequence: Sequence, predicate: Predicate): number export function lastIndex(sequence: Sequence, predicate?: Predicate): number { return resetOmniSequence(sequence).lastIndex(predicate as Predicate) } /** * Static version of [[OmniSequence.map]] that works on any sequence. */ export function map(sequence: Sequence, transform: Transform): OmniSequence<[OK, OV]> export function map(sequence: Sequence, transform: Transform): OmniSequence export function map(sequence: Sequence, transform: Transform): OmniSequence { return getOmniSequence(sequence).map(transform) } /** * Static version of [[OmniSequence.max]] that works on any sequence. */ export function max(sequence: Sequence): number export function max(sequence: Sequence, transform: Transform): T export function max(sequence: Sequence, transform?: Transform): T | number { return resetOmniSequence(sequence).max(transform as Transform) } /** * Static version of [[OmniSequence.mean]] that works on any sequence. */ export function mean(sequence: Sequence): number { return resetOmniSequence(sequence).mean() } /** * Static version of [[OmniSequence.min]] that works on any sequence. */ export function min(sequence: Sequence): number export function min(sequence: Sequence, transform: Transform): T export function min(sequence: Sequence, transform?: Transform): T | number { return resetOmniSequence(sequence).min(transform as Transform) } /** * Static version of [[OmniSequence.none]] that works on any sequence. */ export function none(sequence: Sequence): boolean export function none(sequence: Sequence, predicate: Predicate): boolean export function none(sequence: Sequence, predicate?: Predicate): boolean { return resetOmniSequence(sequence).none(predicate as Predicate) } /** * Static version of [[OmniSequence.partition]] that works on any sequence. */ export function partition(sequence: Sequence, predicate: Predicate): [T[], T[]] { return resetOmniSequence(sequence).partition(predicate) } /** * Static version of [[OmniSequence.permute]] that works on any sequence. */ export function permute(sequence: Sequence): OmniSequence { return resetOmniSequence(sequence).permute() } /** * Static version of [[OmniSequence.prepend]] that works on any sequence. */ export function prepend(sequence: Sequence, ...elements: T[]): OmniSequence { return getOmniSequence(sequence).prepend(...elements) } /** * Static version of [[OmniSequence.rank]] that works on any sequence. */ export function rank(sequence: Sequence, transform: Transform): OmniSequence { return getOmniSequence(sequence).rank(transform) } /** * Static version of [[OmniSequence.remove]] that works on any sequence. */ export function remove(sequence: Sequence, predicate: Predicate): OmniSequence export function remove(sequence: Sequence, predicate: Predicate, count: number): OmniSequence export function remove(sequence: Sequence, predicate: Predicate, count?: number): OmniSequence { return getOmniSequence(sequence).remove(predicate, count as number) } /** * Static version of [[OmniSequence.removeLast]] that works on any sequence. */ export function removeLast(sequence: Sequence, predicate: Predicate, count: number): OmniSequence { return getOmniSequence(sequence).removeLast(predicate, count) } /** * Static version of [[OmniSequence.repeat]] that works on any sequence. */ export function repeat(sequence: Sequence): OmniSequence export function repeat(sequence: Sequence, count: number): OmniSequence export function repeat(sequence: Sequence, count?: number): OmniSequence { return getOmniSequence(sequence).repeat(count as number) } /** * Static version of [[OmniSequence.replace]] that works on any sequence. */ export function replace(sequence: Sequence, predicate: Predicate, replacement: R): OmniSequence export function replace(sequence: Sequence, predicate: Predicate, replacement: R, count: number): OmniSequence export function replace(sequence: Sequence, predicate: Predicate, replacement: R, count?: number): OmniSequence { return getOmniSequence(sequence).replace(predicate, replacement, count as number) } /** * Static version of [[OmniSequence.replaceLast]] that works on any sequence. */ export function replaceLast(sequence: Sequence, predicate: Predicate, replacement: R, count: number): OmniSequence { return getOmniSequence(sequence).replaceLast(predicate, replacement, count) } /** * Static version of [[OmniSequence.reversed]] that works on any sequence. */ export function reversed(sequence: Sequence): OmniSequence { return getOmniSequence(sequence).reversed() } /** * Static version of [[OmniSequence.set]] that works on any sequence. */ export function set(sequence: Sequence, index: number, element: T): OmniSequence { return getOmniSequence(sequence).set(index, element) } /** * Static version of [[OmniSequence.slice]] that works on any sequence. */ export function slice(sequence: Sequence, start: number, end: number): OmniSequence { return getOmniSequence(sequence).slice(start, end as number) } /** * Static version of [[OmniSequence.some]] that works on any sequence. */ export function some(sequence: Sequence): boolean export function some(sequence: Sequence, predicate: Predicate): boolean export function some(sequence: Sequence, predicate?: Predicate): boolean { return resetOmniSequence(sequence).some(predicate as Predicate) } /** * Static version of [[OmniSequence.sort]] that works on any sequence. */ export function sort(sequence: Sequence): OmniSequence export function sort(sequence: Sequence, descending: boolean): OmniSequence export function sort(sequence: Sequence): OmniSequence export function sort(sequence: Sequence, descending: boolean): OmniSequence export function sort(sequence: Sequence, comparator: Comparator): OmniSequence export function sort(sequence: Sequence, second?: Comparator | boolean): OmniSequence { return getOmniSequence(sequence).sort(second as any) } /** * Static version of [[OmniSequence.startsWith]] that works on any sequence. */ export function startsWith(sequence: Sequence, prefix: Sequence): boolean export function startsWith(sequence: Sequence, prefix: Sequence, equals: PairPredicate): boolean export function startsWith(sequence: Sequence, prefix: Sequence, equals?: PairPredicate): boolean { return resetOmniSequence(sequence).startsWith(prefix, equals as PairPredicate) } /** * Static version of [[OmniSequence.sum]] that works on any sequence. */ export function sum(sequence: Sequence): number { return resetOmniSequence(sequence).sum() } /** * Static version of [[OmniSequence.swap]] that works on any sequence. */ export function swap(sequence: Sequence, first: number, second: number): OmniSequence { return getOmniSequence(sequence).swap(first, second) } /** * Static version of [[OmniSequence.take]] that works on any sequence. */ export function take(sequence: Sequence): OmniSequence export function take(sequence: Sequence, count: number): OmniSequence export function take(sequence: Sequence, predicate: Predicate): OmniSequence export function take(sequence: Sequence, argument?: number | Predicate): OmniSequence { return getOmniSequence(sequence).take(argument as any) } /** * Static version of [[OmniSequence.takeLast]] that works on any sequence. */ export function takeLast(sequence: Sequence, count: number): OmniSequence export function takeLast(sequence: Sequence, predicate: Predicate): OmniSequence export function takeLast(sequence: Sequence, argument: number | Predicate): OmniSequence { return getOmniSequence(sequence).takeLast(argument as any) } /** * Static version of [[OmniSequence.toArray]] that works on any sequence. */ export function toArray(sequence: Sequence): T[] export function toArray(sequence: Sequence, destination: T[]): T[] export function toArray(sequence: Sequence, destination: T[], clear: boolean): T[] export function toArray(sequence: Sequence, destination?: T[], clear?: boolean): T[] { return resetOmniSequence(sequence).toArray(destination as T[], clear as boolean) } /** * Static version of [[OmniSequence.toMap]] that works on any sequence. */ export function toMap(sequence: Sequence<[K, V]>): Map export function toMap(sequence: Sequence<[K, V]>, destination: Map): Map export function toMap(sequence: Sequence<[K, V]>, destination: Map, clear: boolean): Map export function toMap(sequence: Sequence<[K, V]>, destination?: Map, clear: boolean = false): Map { return resetOmniSequence(sequence).toMap(destination as Map, clear as boolean) } /** * Static version of [[OmniSequence.toObject]] that works on any sequence. */ export function toObject(sequence: Sequence<[string, T]>): Dictionary export function toObject(sequence: Sequence<[string, T]>, destination: Dictionary): Dictionary export function toObject(sequence: Sequence<[string, T]>, destination: Dictionary, clear: boolean): Dictionary export function toObject(sequence: Sequence<[string, T]>, destination?: Dictionary, clear: boolean = false): Dictionary { return resetOmniSequence(sequence).toObject(destination as Dictionary, clear as boolean) } /** * Static version of [[OmniSequence.toSet]] that works on any sequence. */ export function toSet(sequence: Sequence): Set export function toSet(sequence: Sequence, destination: Set): Set export function toSet(sequence: Sequence, destination: Set, clear: boolean): Set export function toSet(sequence: Sequence, destination?: Set, clear?: boolean): Set { return resetOmniSequence(sequence).toSet(destination as Set, clear as boolean) } /** * Static version of [[OmniSequence.union]] that works on any sequence. */ export function union(sequence: Sequence, other: Sequence): OmniSequence export function union(sequence: Sequence, other: Sequence, transform: Transform): OmniSequence export function union(sequence: Sequence, other: Sequence, transform?: Transform): OmniSequence { return getOmniSequence(sequence).union(other, transform as Transform) } /** * Static version of [[OmniSequence.unique]] that works on any sequence. */ export function unique(sequence: Sequence): OmniSequence export function unique(sequence: Sequence, transform: Transform): OmniSequence export function unique(sequence: Sequence, transform?: Transform): OmniSequence { return getOmniSequence(sequence).unique(transform as Transform) } /** * Static version of [[OmniSequence.zip]] that works on any sequence. */ export function zip(sequence: Sequence, other: Sequence): OmniSequence<[T, V]> { return getOmniSequence(sequence).zip(other) }