Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 16 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,15 @@ Operators:

Transformers
- where : filter iterable by predicate
- filter : alias for where
- select : transform iterable using mapping function
- map : alias for select
- selectMany : flatten an iterable and can transform it to another iterable
- flat: flatten an iterable up to N levels, default is 1 level
- flatMap: flatten an iterable one level and maps inner elements
- ofType : produces typed iterable, used to filter by type
- ofClass: filters iterable for elements of a given class
- groupBy: group items by a key
- orderBy : Order iterable ascending by a key
- orderByDescending : Order iterable descending by a key
- groupJoin: Do a group join (left join) between current and external iterable. For each item of current sequence get array of items from external sequence.
Expand All @@ -73,36 +78,43 @@ Combinations:
- union: Produce a union of two iterables where the result is distinct values from both.
- intersect: Return an intersection of two iterables where the result is distinct values.
- difference: Return elements from the first iterable that are not in the second. Only distinct values are returned.
- except: Return elements from the first iterable that are not in the second. (TODO)
- symmetricDifference: Return a symmetric difference ( distinct values except intersection ) of two iterables where the result is distinct values.

Aggregators:
- toArray(): convert iterable to array
- toMap(): Create a map object from sequence
- toSet(): Creates a set from current sequence
- first : first element in iterable or first element that satisfies predicate
- find: alias for first
- firstOrDefault: like first but with default value
- firstOrThrows: like first but throws if no element is found
- firstOrThrow: like first but throws if no element is found
- firstIndex: like first but returns index of element
- findIndex: alias for firstIndex
- last: last element in iterable or last element that satisfies predicate
- findLast: alias for last
- lastOrDefault: like last but with default value
- lastOrThrows: like last but throws if no element is found
- lastOrThrow: like last but throws if no element is found
- lastIndex: like last but returns index of element
- findLastIndex: alias for lastIndex
- single: single element in iterable or single element that satisfies predicate. Throws if more than one element is found.
- singleOrDefault: like single but with default value when nothing found. Throws if more than one element is found.
- all: check if all elements in iterable satisfy predicate
- every: alias for all
- allAndEvery: like all but requires to have at least one element
- any: check if at least one element in iterable satisfies predicate
- some: alias for any
- count: count elements in iterable or count of elements that satisfy predicate
- aggregate: Produce single value form sequence values. The initial value is the second argument.
- reduce: alias for aggregate
- sum: Sum all elements in iterable
- product: Multiply all elements in iterable
- min: Get minimum value in iterable
- max: Get maximum value in iterable
- join: join all items from iterable with string concatenation
- elementAt: get element at index
- at: alias for elementAt

Misc:
- forEach: iterate over iterable and execute a function for each element
- isEqual: check if two iterables are equal. Same elements and order.
- isElementsEqual: check if two iterables are equal. Same elements but order can be different.
- isElementsEqual: check if two iterables are equal. Same elements but order can be different.
159 changes: 120 additions & 39 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,39 @@ declare module 'fluent-iter' {
*/
where<TSubValue extends TValue>(predicate: (item: TValue) => item is TSubValue): FluentIterable<TSubValue>;

/**
* Filters the iterable using predicate function typed overload. Alias to where.
* @see where
* @param predicate
*/
filter<TSubValue extends TValue>(predicate: (item: TValue) => item is TSubValue): FluentIterable<TSubValue>;

/**
* Filters the iterable using predicate function
* @param predicate
*/
where(predicate: (item: TValue) => boolean): FluentIterable<TValue>;

/**
* Filters the iterable using predicate function. Alias to where.
* @see where
* @param predicate
*/
filter(predicate: (item: TValue) => boolean): FluentIterable<TValue>;

/**
* Maps the iterable items
* @param map map function
*/
select<TOutput>(map: (item: TValue) => TOutput): FluentIterable<TOutput>;

/**
* Maps the iterable items. Alias to select.
* @see select
* @param map map function
*/
map<TOutput>(map: (item: TValue) => TOutput): FluentIterable<TOutput>;

/**
* Flat Iterable of collections up to N levels, default is 1 level.
* @param depth
Expand Down Expand Up @@ -274,6 +295,13 @@ declare module 'fluent-iter' {
*/
first(predicate?: (item: TValue) => boolean): TValue | undefined;

/**
* Get first item of iterable satisfiying the predicate. Alias for first.
* @see first
* @param predicate predicate for the item
*/
find(predicate: (item: TValue) => boolean): TValue | undefined;

/**
* Get first item of iterable, if does not contain any return default
* @param def
Expand All @@ -293,12 +321,27 @@ declare module 'fluent-iter' {
*/
firstIndex(predicate: (item: TValue) => boolean): number;

/**
* Get index of first found item in sequence. Alias for firstIndex.
* @see firstIndex
* @param predicate predicate for the item
* @return index of item, when not found -1
*/
findIndex(predicate: (item: TValue) => boolean): number;

/**
* Get last item of iterable
* @param predicate optional predicate for the item
*/
last(predicate?: (item: TValue) => boolean): TValue | undefined;

/**
* Get last item of iterable satisfiying the predicate. Alias for last
* @see last
* @param predicate optional predicate for the item
*/
findLast(predicate: (item: TValue) => boolean): TValue | undefined;

/**
* Get last item of iterable, if does not contain any return default
* @param def
Expand All @@ -319,6 +362,14 @@ declare module 'fluent-iter' {
*/
lastIndex(predicate: (item: TValue) => boolean): number;

/**
* Get index of last found item in sequence satisfiying the predicate. Alias for lastIndex.
* @see lastIndex
* @param predicate predicate for the item
* @return index of item, when not found -1
*/
findLastIndex(predicate: (item: TValue) => boolean): number;

/**
* Checks if iterable has only one item and returns it.
* @throws TypeError when no or multiple elements
Expand All @@ -338,6 +389,13 @@ declare module 'fluent-iter' {
*/
all(predicate: (item: TValue) => boolean): boolean;

/**
* Returns if all items satisfy the predicate. It returns true if no items. Alias for all.
* @see all
* @param predicate
*/
every(predicate: (item: TValue) => boolean): boolean;

/**
* Returns if all items satisfy the predicate. It returns false if no items.
* @param predicate
Expand All @@ -350,6 +408,13 @@ declare module 'fluent-iter' {
*/
any(predicate?: (item: TValue) => boolean): boolean;

/**
* Returns if any items satisfy the predicate. Alias for any.
* @see any
* @param predicate
*/
some(predicate?: (item: TValue) => boolean): boolean;

/**
* Return count of items.
* @param predicate if predicate is supplied then return the count of items that return true.
Expand All @@ -363,13 +428,29 @@ declare module 'fluent-iter' {
*/
aggregate(accumulator: (result: TValue, item: TValue, index: number) => TValue): TValue | never;

/**
* Produce single value form sequence values. The initial value is first element. Alias for aggregate.
* @see aggregate
* @param accumulator function which produces the result.
* @throws TypeError when no elements
*/
reduce(accumulator: (result: TValue, item: TValue, index: number) => TValue): TValue | never;

/**
* Produce single value form sequence values. The initial value is the second argument.
* @param accumulator function which produces the result.
* @param initial initial value
*/
aggregate<TResult>(accumulator: (result: TResult, item: TValue, index: number) => TResult, initial: TResult): TResult;

/**
* Produce single value form sequence values. The initial value is the second argument. Alias for aggregate.
* @see aggregate
* @param accumulator function which produces the result.
* @param initial initial value
*/
reduce<TResult>(accumulator: (result: TResult, item: TValue, index: number) => TResult, initial: TResult): TResult;

/**
* Produce a sum of sequence values
* @throws {TypeError} if not items in sequence
Expand Down Expand Up @@ -409,6 +490,14 @@ declare module 'fluent-iter' {
*/
elementAt(index: number): TValue | undefined;

/**
* Return element at specific index. Alias for elementAt.
* @see elementAt
* @param index index of requested element.
* @return undefined when no index out of range.
*/
at(index: number): TValue | undefined;

/**
* do action over every item in the sequence
* @param action
Expand Down Expand Up @@ -437,63 +526,69 @@ declare module 'fluent-iter' {
key: TKey;
}

export interface FluentIterableAsync<TValue> extends AsyncIterable<TValue> {
export interface FluentAsyncIterable<TValue> extends AsyncIterable<TValue> {
/**
* Filters the iterable using predicate function typed overload
* @param predicate
*/
where<TSubValue extends TValue>(predicate: (item: TValue) => item is TSubValue): FluentIterableAsync<TSubValue>;
where<TSubValue extends TValue>(predicate: (item: TValue) => item is TSubValue): FluentAsyncIterable<TSubValue>;

/**
* Filters the iterable using predicate function
* @param predicate
*/
where(predicate: (item: TValue) => boolean): FluentIterableAsync<TValue>;
where(predicate: (item: TValue) => boolean): FluentAsyncIterable<TValue>;
/**
* Maps the iterable items
* @param map map function
*/
select<TOutput>(map: (item: TValue) => TOutput): FluentIterableAsync<TOutput>;
select<TOutput>(map: (item: TValue) => TOutput): FluentAsyncIterable<TOutput>;

/**
* Take first N items from iterable
*/
take(count: number): FluentIterableAsync<TValue>;
take(count: number): FluentAsyncIterable<TValue>;

/**
* Return items while condition return true
* @param condition
*/
takeWhile(condition: (item: TValue, index: number) => boolean): FluentIterableAsync<TValue>;
takeWhile(condition: (item: TValue, index: number) => boolean): FluentAsyncIterable<TValue>;

/**
* Skip first N items from iterable
* @param count
*/
skip(count: number): FluentIterableAsync<TValue>;
skip(count: number): FluentAsyncIterable<TValue>;

/**
* Skip items while condition return true, get the rest
* @param condition
*/
skipWhile(condition: (item: TValue, index: number) => boolean): FluentIterableAsync<TValue>;
skipWhile(condition: (item: TValue, index: number) => boolean): FluentAsyncIterable<TValue>;

/**
* Return distinct items. Can specify optional item comparer
* @param keySelector function to get key for comparison.
*/
distinct<TKey>(keySelector?: (item: TValue) => TKey): FluentIterableAsync<TValue>;
distinct<TKey>(keySelector?: (item: TValue) => TKey): FluentAsyncIterable<TValue>;

/**
* Group items
* @param keySelector group key selector
*/
groupBy<TKey>(keySelector: (item: TValue, index: number) => TKey):
[TKey, TValue] extends ['fulfilled' | 'rejected', PromiseResult<infer TPromiseValue>]
? FluentIterableAsync< IGrouping<'fulfilled', FulfilledPromiseResult<TPromiseValue>> | IGrouping<'rejected', RejectedPromiseResult>>
: FluentIterableAsync<IGrouping<TKey, TValue>>;
groupBy<TKey, TElement>(keySelector: (item: TValue, index: number) => TKey, elementSelector: (item: TValue, index: number) => TElement): FluentIterableAsync<IGrouping<TKey, TElement>>;
groupBy<TKey, TElement, TResult>(keySelector: (item: TValue, index: number) => TKey, elementSelector: (item: TValue, index: number) => TElement, resultCreator: (key: TKey, items: FluentIterable<TElement>) => TResult): FluentIterableAsync<TResult>;
[TKey, TValue] extends ['fulfilled' | 'rejected', PromiseSettledResult<infer TPromiseValue>]
? FluentAsyncIterable< IGrouping<'fulfilled', PromiseFulfilledResult<TPromiseValue>> | IGrouping<'rejected', PromiseRejectedResult>>
: FluentAsyncIterable<IGrouping<TKey, TValue>>;
groupBy<TKey, TElement>(keySelector: (item: TValue, index: number) => TKey, elementSelector: (item: TValue, index: number) => TElement): FluentAsyncIterable<IGrouping<TKey, TElement>>;
groupBy<TKey, TElement, TResult>(keySelector: (item: TValue, index: number) => TKey, elementSelector: (item: TValue, index: number) => TElement, resultCreator: (key: TKey, items: FluentIterable<TElement>) => TResult): FluentAsyncIterable<TResult>;

/**
* Create a paging
* @param pageSize
*/
page(pageSize: number): FluentAsyncIterable<TValue[]>;

/**
* Return a promise to an array.
Expand All @@ -506,7 +601,7 @@ declare module 'fluent-iter' {
* @param keySelector - key selector - keys should be unique, otherwise last keys will override first.
*/
toMap<TKey>(keySelector: (item: TValue) => TKey):
[TKey, TValue] extends ['fulfilled' | 'rejected', IGrouping<'fulfilled', FulfilledPromiseResult<infer TPromiseValue>> | IGrouping<'rejected', RejectedPromiseResult>]
[TKey, TValue] extends ['fulfilled' | 'rejected', IGrouping<'fulfilled', PromiseFulfilledResult<infer TPromiseValue>> | IGrouping<'rejected', PromiseRejectedResult>]
? Promise<PromiseMap<TPromiseValue>>
: Promise<Map<TKey, TValue>>;

Expand All @@ -518,28 +613,14 @@ declare module 'fluent-iter' {
toMap<TKey, TElement>(keySelector: (item: TValue) => TKey, elementSelector: (item: TValue) => TElement): Promise<Map<TKey, TElement>>;
}

export interface FluentIterableAsyncPromise<T> extends FluentIterableAsync<PromiseResult<T>> {
groupByStatus(): FluentIterableAsync< IGrouping<'fulfilled', FulfilledPromiseResult<T>> | IGrouping<'rejected', RejectedPromiseResult>>;
export interface FluentAsyncIterablePromise<T> extends FluentAsyncIterable<PromiseSettledResult<T>> {
groupByStatus(): FluentAsyncIterable< IGrouping<'fulfilled', PromiseFulfilledResult<T>> | IGrouping<'rejected', PromiseRejectedResult>>;
toStatusMap(): Promise<PromiseMap<T>>;
}

type PromiseResult<T> = FulfilledPromiseResult<T> | RejectedPromiseResult;

interface FulfilledPromiseResult<T> {
index: number;
status: 'fulfilled';
value: T;
}

interface RejectedPromiseResult {
index: number;
status: 'rejected';
reason: any;
}

interface PromiseMap<T> extends Map<'fulfilled'|'rejected', FluentIterable<PromiseResult<T>>> {
get(key: 'fulfilled'): FluentIterable<FulfilledPromiseResult<T>> | undefined;
get(key: 'rejected'): FluentIterable<RejectedPromiseResult> | undefined;
interface PromiseMap<T> extends Map<'fulfilled'|'rejected', FluentIterable<PromiseSettledResult<T>>> {
get(key: 'fulfilled'): FluentIterable<PromiseFulfilledResult<T>> | undefined;
get(key: 'rejected'): FluentIterable<PromiseRejectedResult> | undefined;
}

type FlatFluentIterable<Value> = Value extends ReadonlyArray<infer InnerArr>
Expand All @@ -558,9 +639,9 @@ declare module 'fluent-iter' {
export function fromObject<TValue extends {}, TKey extends keyof TValue>(value: TValue): FluentIterable<{ key: string, value: TValue[TKey] }>;
export function fromObject<TValue extends {}, TKey extends keyof TValue, TResult>(value: TValue, resultCreator: (key: TKey, value: TValue[TKey]) => TResult): FluentIterable<TResult>;

export function fromEvent<TTarget extends EventTarget, TEvent extends keyof HTMLElementEventMap>(target: TTarget, event: TEvent): FluentIterableAsync<HTMLElementEventMap[TEvent]>;
export function fromTimer(interval: number, delay?: number): FluentIterableAsync<number>;
export function fromPromises<T>(...promises: Promise<T>[]): FluentIterableAsyncPromise<T>;
export function isFulfilled<T>(result: PromiseResult<T>): result is FulfilledPromiseResult<T>;
export function isRejected<T>(result: PromiseResult<T>): result is RejectedPromiseResult;
export function fromEvent<TTarget extends EventTarget, TEvent extends keyof HTMLElementEventMap>(target: TTarget, event: TEvent): FluentAsyncIterable<HTMLElementEventMap[TEvent]>;
export function fromTimer(interval: number, delay?: number): FluentAsyncIterable<number>;
export function fromPromises<T>(...promises: Promise<T>[]): FluentAsyncIterablePromise<T>;
export function isFulfilled<T>(result: PromiseSettledResult<T>): result is PromiseFulfilledResult<T>;
export function isRejected<T>(result: PromiseSettledResult<T>): result is PromiseRejectedResult;
}
Loading