@adamburgess/linq

    Interface AnySequence<T>

    A sequence of values.

    To create me, use from:

    const sequence = from(['an', 'iterable', 'here!']);
    // now use all the methods on sequence!
    interface AnySequence<T> {
        "[iterator]"(): Iterator<T>;
        all(predicate: (arg: T) => any): boolean;
        any(predicate: (arg: T) => any): boolean;
        any(): boolean;
        append<TAppend>(iterable: Iterable<TAppend>): Sequence<T | TAppend>;
        average(f: (arg: T) => number): number;
        contains(value: T): boolean;
        count(): number;
        distinct(): Sequence<T>;
        distinct(keySelector: (arg: T) => unknown): Sequence<T>;
        first(): T;
        first(predicate: (arg: T) => any): T;
        firstOrDefault(): undefined | T;
        firstOrDefault(predicate: (arg: T) => any): undefined | T;
        flat<TProject>(
            projector: (input: T) => Iterable<TProject>,
        ): Sequence<TProject>;
        groupBy<TKey>(
            keySelector: (arg: T) => TKey,
        ): ArraySequence<KeySequence<TKey, T>>;
        groupBy<TKey, TProject>(
            keySelector: (arg: T) => TKey,
            elementSelector: (arg: T) => TProject,
        ): ArraySequence<KeySequence<TKey, TProject>>;
        groupJoin<TInner, TKey, TResult>(
            innerSequence: Iterable<TInner>,
            outerKeySelector: (arg: T) => TKey,
            innerKeySelector: (arg: TInner) => TKey,
            resultSelector: (outer: T, inner: Sequence<TInner>) => TResult,
        ): Sequence<TResult>;
        join<TInner, TKey, TResult>(
            innerSequence: Iterable<TInner>,
            outerKeySelector: (arg: T) => TKey,
            innerKeySelector: (arg: TInner) => TKey,
            resultSelector: (outer: T, inner: TInner) => TResult,
        ): Sequence<TResult>;
        last(): T;
        last(predicate: (arg: T) => any): T;
        lastOrDefault(): undefined | T;
        lastOrDefault(predicate: (arg: T) => any): undefined | T;
        map<TResult>(f: (arg: T, index: number) => TResult): Sequence<TResult>;
        max(f: (arg: T) => number): number;
        maxBy(f: (arg: T) => number): T;
        min(f: (arg: T) => number): number;
        minBy(f: (arg: T) => number): T;
        none(predicate: (arg: T) => any): boolean;
        orderBy(keySelector: (arg: T) => string | number): OrderedSequence<T>;
        orderBy<TKey>(
            keySelector: (arg: T) => TKey,
            comparer: ICompare<TKey>,
        ): OrderedSequence<T>;
        orderByDescending(
            keySelector: (arg: T) => string | number,
        ): OrderedSequence<T>;
        orderByDescending<TKey>(
            keySelector: (arg: T) => TKey,
            comparer: ICompare<TKey>,
        ): OrderedSequence<T>;
        prepend<TPrepend>(iterable: Iterable<TPrepend>): Sequence<T | TPrepend>;
        reverse(): Sequence<T>;
        single(): T;
        single(predicate: (arg: T) => any): T;
        singleOrDefault(): undefined | T;
        singleOrDefault(predicate: (arg: T) => any): undefined | T;
        skip(count: number): Sequence<T>;
        skipWhile(predicate: (arg: T) => any): Sequence<T>;
        sum(f: (arg: T) => number): number;
        take(count: number): Sequence<T>;
        takeWhile(predicate: (arg: T) => any): Sequence<T>;
        toArray(): T[];
        toMap<TKey, TElement>(
            keySelector: (arg: T) => TKey,
            elementSelector: (arg: T) => TElement,
        ): Map<TKey, TElement>;
        toObject<TKey extends PropertyKey, TElement>(
            keySelector: (arg: T) => TKey,
            elementSelector: (arg: T) => TElement,
        ): Record<TKey, TElement>;
        toSet(): Set<T>;
        toSet<TProject>(projector: (arg: T) => TProject): Set<TProject>;
        where<TNarrowed>(
            f: (arg: T | TNarrowed, index: number) => arg is TNarrowed,
        ): Sequence<TNarrowed>;
        where<TNarrowed>(
            f: (arg: T | TNarrowed, index: number) => boolean,
        ): Sequence<TNarrowed>;
        where(f: (arg: T, index: number) => any): Sequence<T>;
    }

    Type Parameters

    • T

    Hierarchy (View Summary, Expand)

    Index

    Methods

    • Iterates through this sequence.

      Returns Iterator<T>

    • True if all elements pass the predicate

      from([2, 1, 5]).all(x => x >= 1)
      // => true
      from([2, 1, 5]).all(x => x >= 2)
      // => false

      Parameters

      • predicate: (arg: T) => any

      Returns boolean

    • True if any elements pass the predicate

      from([2, 1, 5]).any(x => x >= 4)
      // => true
      from([2, 1, 5]).any(x => x <= 0)
      // => false

      Parameters

      • predicate: (arg: T) => any

      Returns boolean

    • True if the sequence is not empty

      from([2, 1, 5]).any()
      // => true
      from([]).any()
      // => false

      Returns boolean

    • Projects each element to a number and averages the sequence. If empty, throws.

      from(['2', '1', '6']).average(x => parseFloat(x))
      // => 3

      Parameters

      • f: (arg: T) => number

      Returns number

    • True if the element is in the sequence. Checked with ===.

      from([2, 1, 5]).contains(1)
      // => true
      from([{ a: '1' }]).contains({ a: '1' })
      // => false (strict equality. use any with a custom search instead.)

      Parameters

      • value: T

      Returns boolean

    • Counts the number of elements in the sequence

      from([2, 1, 5]).count()
      // => 3
      from([]).count()
      // => 0

      Returns number

    • Get all distinct elements of the sequence using strict equality. First value wins.

      from([1, 2, 2, 3]).distinct()
      // => [1, 2, 3]

      Returns Sequence<T>

    • Get all distinct elements of the sequence, mapping each element to a key that will be used for strict equality. First value wins.

      from([10, 15, 20, 25, 30]).distinct(x => Math.trunc(x / 10))
      // => [10, 20, 30]

      Parameters

      • keySelector: (arg: T) => unknown

      Returns Sequence<T>

    • Get the first element in the sequence. Will throw if empty! Use firstOrDefault if no throw is wanted.

      from([2, 1, 5]).first()
      // => 2
      from([]).first()
      // => throws

      Returns T

    • Get the first element in the sequence that matches a condition. Will throw if empty! Use firstOrDefault if no throw is wanted.

      from([2, 1, 5]).first(x => x >= 4)
      // => 5
      from([2, 1, 5]).first(x => x < 0)
      // => throws

      Parameters

      • predicate: (arg: T) => any

      Returns T

    • Get the first element in the sequence. If empty, returns undefined.

      from([2, 1, 5]).firstOrDefault()
      // => 2
      from([]).firstOrDefault()
      // => undefined

      Returns undefined | T

    • Get the first element in the sequence that matches a condition. If empty or no matches, returns undefined.

      from([2, 1, 5]).firstOrDefault(x => x >= 4)
      // => 5
      from([2, 1, 5]).firstOrDefault(x => x < 0)
      // => undefined

      Parameters

      • predicate: (arg: T) => any

      Returns undefined | T

    • Project each element to an iterable/array, then flatten the result

      from(['1 2', '3 4']).flat(x => x.split(' '))
      // => ['1', '2', '3', '4']

      Type Parameters

      • TProject

      Parameters

      Returns Sequence<TProject>

    • Project each element to get a key, and group all items by that key.

      from([10, 15, 20]).groupBy(x => Math.trunc(x / 10))
      .map(g => ({ key: g.key, values: Array.from(g) }))
      // => [{ key: 1, values: [10, 15] },
      // { key: 2, values: [20] }]

      Type Parameters

      • TKey

      Parameters

      • keySelector: (arg: T) => TKey

      Returns ArraySequence<KeySequence<TKey, T>>

    • Project each element to get a key, and group all items, each projected onto another type.

      from([10, 15, 20]).groupBy(x => Math.trunc(x / 10), x => x.toString())
      .map(g => ({ key: g.key, values: Array.from(g) }))
      // => [{ key: 1, values: ['10', '15'] },
      // { key: 2, values: ['20'] }]

      Type Parameters

      • TKey
      • TProject

      Parameters

      Returns ArraySequence<KeySequence<TKey, TProject>>

    • Correlates the elements of two sequences based on matching keys, and groups everything in the other table.

      const appleTypes = [
      { name: 'green apple', id: 5 },
      { name: 'red apple', id: 2 },
      { name: 'yellow apple', id: 10 }
      ];
      const apples = [
      { name: 'golden delicious', type: 10 },
      { name: 'granny smith', type: 5 },
      { name: 'pink lady', type: 2 },
      { name: 'fuji', type: 2 },
      { name: 'unknown', type: 999 }
      ];

      from(appleTypes).groupJoin(
      apples,
      type => type.id,
      apple => apple.type,
      (type, apples) => `${type.name}: ${apples.map(a => a.name).joinString(', ')}`
      );
      // => [ 'green apple: granny smith',
      // 'red apple: pink lady, fuji',
      // 'yellow apple: golden delicious' ]

      Type Parameters

      • TInner
      • TKey
      • TResult

      Parameters

      Returns Sequence<TResult>

    • Correlates the elements of two sequences based on matching keys. An inner join.

      const appleTypes = [
      { name: 'green apple', id: 5 },
      { name: 'red apple', id: 2 },
      { name: 'yellow apple', id: 10 }
      ];
      const apples = [
      { name: 'golden delicious', type: 10 },
      { name: 'granny smith', type: 5 },
      { name: 'pink lady', type: 2 },
      { name: 'fuji', type: 2 },
      { name: 'unknown', type: 999 }
      ];

      from(apples).join(
      appleTypes,
      apple => apple.type,
      type => type.id,
      (apple, type) => `${apple.name}: ${type.name}`
      )
      // => [ 'golden delicious: yellow apple',
      // 'granny smith: green apple',
      // 'pink lady: red apple',
      // 'fuji: red apple' ]

      Type Parameters

      • TInner
      • TKey
      • TResult

      Parameters

      Returns Sequence<TResult>

    • Get the last element in the sequence. Will throw if empty! Use lastOrDefault if no throw is wanted.

      from([2, 1, 5]).last()
      // => 5
      from([]).last()
      // => throws

      Returns T

    • Get the last element in the sequence that matches a condition. Will throw if empty! Use lastOrDefault if no throw is wanted.

      from([2, 1, 5]).last(x => x < 4)
      // => 1
      from([]).last(x => x < 0)
      // => throws

      Parameters

      • predicate: (arg: T) => any

      Returns T

    • Get the last element in the sequence. If empty, returns undefined.

      from([2, 1, 5]).lastOrDefault()
      // => 5
      from([]).lastOrDefault()
      // => undefined

      Returns undefined | T

    • Get the last element in the sequence that matches a condition. If empty or no matches, returns undefined.

      from([2, 1, 5]).lastOrDefault(x => x < 4)
      // => 1
      from([2, 1, 5]).lastOrDefault(x => x < 0)
      // => undefined

      Parameters

      • predicate: (arg: T) => any

      Returns undefined | T

    • Projects each element to a number and finds the max of the sequence. If empty, throws.

      from(['2', '1', '5']).max(x => parseFloat(x))
      // => 5

      Parameters

      • f: (arg: T) => number

      Returns number

    • Finds the maximum element in the sequence according to a selector. Equivalent (but faster) to orderByDescending(f).first().

      from([{ key: 'A', value: 2 }, { key: 'B', value: 1 }, { key: 'C', value: 10 }]).maxBy(x => x.value)
      // => { key: 'C', value: 10 }

      Parameters

      • f: (arg: T) => number

      Returns T

    • Projects each element to a number and finds the min of the sequence. If empty, throws.

      from(['2', '1', '5']).min(x => parseFloat(x))
      // => 1

      Parameters

      • f: (arg: T) => number

      Returns number

    • Finds the minimum element in the sequence according to a selector. Equivalent (but faster) to orderBy(f).first().

      from([{ key: 'A', value: 2 }, { key: 'B', value: 1 }, { key: 'C', value: 10 }]).minBy(x => x.value)
      // => { key: 'B', value: 1 }

      Parameters

      • f: (arg: T) => number

      Returns T

    • True if no elements pass the predicate

      from([2, 1, 5]).none(x => x === 0)
      // => true
      from([2, 1, 5]).none(x => x === 1)
      // => false

      Parameters

      • predicate: (arg: T) => any

      Returns boolean

    • Sort the array in ascending order of the selector

      from([4, 1, 10]).orderBy(x => x)
      // => [1, 4, 10]

      Parameters

      • keySelector: (arg: T) => string | number

      Returns OrderedSequence<T>

    • Sort the array in ascending order of the selector, with a custom comparer

      // Sort alphabetically, ignoring case.
      from(['A xylophone', 'a frog', 'a zoo']).orderBy(x => x, new Intl.Collator('en', { sensitivity: 'base' }).compare)
      // => ['a frog', 'A xylophone', 'a zoo']

      Type Parameters

      • TKey

      Parameters

      Returns OrderedSequence<T>

    • Sort the array in descending order of the selector

      from([4, 1, 10]).orderByDescending(x => x)
      // => [10, 4, 1]

      Parameters

      • keySelector: (arg: T) => string | number

      Returns OrderedSequence<T>

    • Sort the array in descending order of the selector, with a custom comparer

      // Sort reverse alphabetically, ignoring case.
      from(['A xylophone', 'a frog', 'a zoo']).orderByDescending(x => x, new Intl.Collator('en', { sensitivity: 'base' }).compare)
      // => ['a zoo', 'A xylophone', 'a frog']

      Type Parameters

      • TKey

      Parameters

      Returns OrderedSequence<T>

    • Get the only element in the sequence. Will throw if empty or more than one element! Use singleOrDefault if no throw is wanted.

      from([2]).single()
      // => 2
      from([2, 1, 5]).single()
      // => throws
      from([]).single()
      // => throws

      Returns T

    • Get the only element in the sequence that matches a condition. Will throw if empty or more than one element! Use singleOrDefault if no throw is wanted.

      from([2, 1, 5]).single(x => x >= 4)
      // => 5
      from([2, 1, 5]).single(x => x >= 1)
      // => throws

      Parameters

      • predicate: (arg: T) => any

      Returns T

    • Get the only element in the sequence. Returns undefined if empty or more than one element.

      from([2]).singleOrDefault()
      // => 2
      from([2, 1, 5]).singleOrDefault()
      // => undefined

      Returns undefined | T

    • Get the only element in the sequence that matches a condition. Returns undefined if empty or more than one element.

      from([2, 1, 5]).singleOrDefault(x => x >= 4)
      // => 5
      from([2, 1, 5]).singleOrDefault(x => x >= 1)
      // => undefined

      Parameters

      • predicate: (arg: T) => any

      Returns undefined | T

    • Skip a number of elements before letting the rest through

      from([2, 3, 1, 5]).skip(2)
      // => [1, 5]

      Parameters

      • count: number

      Returns Sequence<T>

    • Skip elements while the predicate is true, then take the rest

      from([2, 3, 1, 5]).skipWhile(x => x >= 2)
      // => [1, 5]

      Parameters

      • predicate: (arg: T) => any

      Returns Sequence<T>

    • Projects each element to a number and sums the sequence. If empty, returns 0.

      from(['2', '1', '5']).sum(x => parseFloat(x))
      // => 8

      Parameters

      • f: (arg: T) => number

      Returns number

    • Take a maximum amount of elements

      from([2, 1, 5]).take(2)
      // => [2, 1]

      Parameters

      • count: number

      Returns Sequence<T>

    • Take elements while the predicate is true, then skips the rest

      from([2, 3, 1, 5]).takeWhile(x => x >= 2)
      // => [2, 3]

      Parameters

      • predicate: (arg: T) => any

      Returns Sequence<T>

    • Converts this sequence to an array.
      Note: If you are using this Sequence in a for..of loop, you do not need this -- you can use the sequence directly.

      from([2, 1, 5]).toArray()
      // => [2, 1, 5]

      Returns T[]

    • Converts this sequence to a Map. First key wins.

      from([{ k: 'a', v: 123 }, { k: 'b', v: 456 }]).toMap(x => x.k, x => x.v)
      // => new Map([['a', 123], ['b', 456]])

      Type Parameters

      • TKey
      • TElement

      Parameters

      Returns Map<TKey, TElement>

    • Converts this sequence into an object. First key wins.

      from([{ k: 'a', v: 123 }, { k: 'b', v: 456 }]).toObject(x => x.k, x => x.v)
      // => { a: 123, b: 456 }

      Type Parameters

      • TKey extends PropertyKey
      • TElement

      Parameters

      Returns Record<TKey, TElement>

    • Convert this sequence into a Set

      from([2, 1, 1, 5]).toSet()
      // => new Set([2, 1, 5])

      Returns Set<T>

    • Map each element and convert the resulting sequence into a set

      from([2, 1, 1, 5]).toSet(x => x + 1)
      // => new Set([3, 2, 6])

      Type Parameters

      • TProject

      Parameters

      Returns Set<TProject>

    • Filters with a TS type assertion ('is'), narrowing to that type

      function isNumber(x: number | string): x is number {
      return typeof x === 'number';
      }
      from(['string', 12, 'str']).where(isNumber)
      // => [12]
      // sequence is now Sequence<number>

      Type Parameters

      • TNarrowed

      Parameters

      Returns Sequence<TNarrowed>

    • Filters with and narrows to a type

      from(['string', 12, 'str']).where<number>(x => typeof x === 'number')
      // => [12]
      // sequence is now Sequence<number>

      note! must use generic type! otherwise this overload is not used, and the type is not narrowed.

      Type Parameters

      • TNarrowed

      Parameters

      Returns Sequence<TNarrowed>

    • Filters with a predicate that must return a truthy value

      from([5, 10, 20]).where(x => x >= 8)
      // => [10, 20]

      Parameters

      • f: (arg: T, index: number) => any

      Returns Sequence<T>

    MMNEPVFCICPMFPCPTTAAATR