geninq
Version:
A JavaScript version of the Linq library for Generators
131 lines (127 loc) • 6.2 kB
text/typescript
import "./array";
import { Build, Promised } from "./utils";
declare global {
interface Generator<T = unknown, TReturn = any, TNext = unknown> {
/**
* Correlates the elements of two sequences based on equality of keys
* and groups the results. The default equality comparer is used to compare keys.
* @param inner The sequence to join to the first sequence.
* @param outer_key_selector A function to extract the join key from each element of the first sequence.
* @param inner_key_selector A function to extract the join key from each element of the second sequence.
* @param result_selector A function to create a result element from an element from the first sequence and a collection of matching elements from the second sequence.
* @returns A generator that contains elements of type TResult that are obtained by performing a grouped join on two sequences.
*/
group_join<TKey extends string | number | boolean, TInner, TResult>(
inner: Generator<TInner> | TInner[],
outer_key_selector: (item: T) => TKey,
inner_key_selector: (item: TInner) => TKey,
result_selector: (item: T, attached: Generator<TInner>) => TResult
): Generator<TResult>;
/**
* Correlates the elements of two sequences based on key equality and groups the results.
* A specified comparitor is used to compare keys.
* @param inner The sequence to join to the first sequence.
* @param outer_key_selector A function to extract the join key from each element of the first sequence.
* @param inner_key_selector A function to extract the join key from each element of the second sequence.
* @param result_selector A function to create a result element from an element from the first sequence and a collection of matching elements from the second sequence.
* @param comparitor A comparitor function to hash and compare keys.
* @returns A generator that contains elements of type TResult that are obtained by performing a grouped join on two sequences.
*/
group_join<TKey, TInner, TResult>(
inner: Generator<TInner> | TInner[],
outer_key_selector: (item: T) => TKey,
inner_key_selector: (item: TInner) => TKey,
result_selector: (item: T, attached: Generator<TInner>) => TResult,
comparitor: (a: TKey, b: TKey) => boolean
): Generator<TResult>;
}
interface AsyncGenerator<T = unknown, TReturn = any, TNext = unknown> {
/**
* Correlates the elements of two sequences based on equality of keys
* and groups the results. The default equality comparer is used to compare keys.
* @param inner The sequence to join to the first sequence.
* @param outer_key_selector A function to extract the join key from each element of the first sequence.
* @param inner_key_selector A function to extract the join key from each element of the second sequence.
* @param result_selector A function to create a result element from an element from the first sequence and a collection of matching elements from the second sequence.
* @returns A generator that contains elements of type TResult that are obtained by performing a grouped join on two sequences.
*/
group_join<TKey extends string | number | boolean, TInner, TResult>(
inner: AsyncGenerator<TInner> | Generator<TInner> | TInner[],
outer_key_selector: (item: T) => Promised<TKey>,
inner_key_selector: (item: TInner) => Promised<TKey>,
result_selector: (
item: T,
attached: AsyncGenerator<TInner>
) => Promised<TResult>
): AsyncGenerator<TResult>;
/**
* Correlates the elements of two sequences based on key equality and groups the results.
* A specified comparitor is used to compare keys.
* @param inner The sequence to join to the first sequence.
* @param outer_key_selector A function to extract the join key from each element of the first sequence.
* @param inner_key_selector A function to extract the join key from each element of the second sequence.
* @param result_selector A function to create a result element from an element from the first sequence and a collection of matching elements from the second sequence.
* @param comparitor A comparitor function to hash and compare keys.
* @returns A generator that contains elements of type TResult that are obtained by performing a grouped join on two sequences.
*/
group_join<TKey, TInner, TResult>(
inner: AsyncGenerator<TInner> | Generator<TInner> | TInner[],
outer_key_selector: (item: T) => Promised<TKey>,
inner_key_selector: (item: TInner) => Promised<TKey>,
result_selector: (
item: T,
attached: AsyncGenerator<TInner>
) => Promised<TResult>,
comparitor: (a: TKey, b: TKey) => boolean
): AsyncGenerator<TResult>;
}
}
Build(
"group_join",
function* (
inner,
outer_key_selector,
inner_key_selector,
result_selector,
comparitor = (a, b) => a === b
) {
const inner_array = Array.isArray(inner) ? inner : inner.array();
for (const item of this) {
const key = outer_key_selector(item);
yield result_selector(
item,
(function* () {
for (let i = 0; i < inner_array.length; i++) {
const item = inner_array[i];
const bkey = inner_key_selector(item);
if (comparitor(key, bkey)) yield item;
}
})()
);
}
},
async function* (
inner,
outer_key_selector,
inner_key_selector,
result_selector,
comparitor = (a, b) => a === b
) {
const inner_array = Array.isArray(inner) ? inner : await inner.array();
for await (const item of this) {
const key = await Promise.resolve(outer_key_selector(item));
yield await Promise.resolve(
result_selector(
item,
(async function* () {
for (let i = 0; i < inner_array.length; i++) {
const item = inner_array[i];
const bkey = await Promise.resolve(inner_key_selector(item));
if (comparitor(key, bkey)) yield item;
}
})()
)
);
}
}
);