A library for asynchronous iteration.
async function* generator() {
let id = 1;
while (true) {
yield WebRequest.json<any>('https://jsonplaceholder.typicode.com/todos/' + id++);
}
}
async function first2Uncompleted() {
const q = await queryAsync(generator())
.filter(x => x.completed === false)
.map(x => x.title)
.take(2)
.awaitAll();
console.log(q.toArray());
}
first2Uncompleted();
// [ 'delectus aut autem', 'quis ut nam facilis et officia qui' ]
Check examples folder for more
- average
- concat
- distinct
- entries
- every
- exclude
- filter
- find
- findIndex
- findLast
- findLastIndex
- first
- flat
- forEach
- groupJoin
- includes
- indexOf
- intersect
- join
- keys
- last
- lastIndexOf
- leftJoin
- length
- map
- max
- min
- nth
- prepend
- reduce
- skip
- slice
- some
- sum
- take
- union
- values
Returns the average value.
Syntax
average(): Promise<number>;
average(selector: (element: T, index: number) => number): Promise<number>;
Parameters
selector
- (optional) a value transformer function to apply to each element
For a sequence with no elements returns undefined
.
Example
import { queryAsync } from 'itiriri-async';
queryAsync([41, 42, 43]).average() // returns 42
queryAsync([{value: 1}, {value: 2}]).average(elem => elem.value) // returns 1.5
queryAsync([]).average() // returns undefined
Concatenates the sequence with another one.
Syntax
concat(other: AsyncIterable<T>): AsyncIterableQuery<T>;
Parameters
other
- (required) sequence to concatenate
Example
import { queryAsync } from 'itiriri-async';
queryAsync([1, 2, 3]).concat([4, 5]).toArray() // returns [1, 2, 3, 4, 5]
concat
is a deferred method and is executed only when the result sequence is iterated.
Returns a sequence of unique elements.
Syntax
distinct(): AsyncIterableQuery<T>;
distinct<S>(selector: (element: T) => S): AsyncIterableQuery<T>;
Parameters
selector
- (optional) a value transformer function to be used for comparisons
Example
import { queryAsync } from 'itiriri-async';
queryAsync([1, 42, 3, 4, 1]).distinct().toArray(); // returns [1, 42, 3, 4]
queryAsync([{value: 1}, {value: 2}, {value: 1}])
.distinct(elem => elem.value)
.toArray(); // returns [{value: 1}, {value: 2}]
distinct
is a deferred method and is executed only when the result sequence is iterated.
Returns a sequence of key/value pair for each element and its index.
Syntax
entries(): AsyncIterableQuery<[number, T]>;
Example
import { queryAsync } from 'itiriri-async';
queryAsync(['Alice', 'Bob', 'David']).entries().toArray();
// returns [[0, 'Alice'], [1, 'Bob'], [2, 'David']]
entries
is a deferred method and is executed only when the result sequence is iterated.
Tests whether all the elements pass the predicate.
Syntax
every(predicate: (element: T, index: number) => boolean): boolean;
Parameters
predicate
- (required) function to test for each element
Example
import { queryAsync } from 'itiriri-async';
queryAsync([2, 4, 9]).every(elem => elem > 0); // returns true
queryAsync([7, 23, 3]).every(elem => elem % 3 === 0); // returns false
Returns a sequence of elements not contained in a given sequence.
Syntax
exclude<S>(others: Iterable<T>): AsyncIterableQuery<T>;
exclude<S>(others: Iterable<T>, selector: (element: T) => S): AsyncIterableQuery<T>;
Parameters
others
- (required) a sequence of elements to be excludedselector
- (optional) a value transformer function to be used for comparisons
Example
import { queryAsync } from 'itiriri-async';
queryAsync([2, 0, 1, 8, 2]).exclude([0, 1]).toArray(); // returns [2, 8, 2]
queryAsync([{id: 1}, {id: 2}])
.exclude([{id: 2}, elem => elem.id])
.toArray(); // returns [{id: 1}]
exclude
is a deferred method and is executed only when the result sequence is iterated.
Returns a sequence of elements that pass the predicate.
Syntax
filter(predicate: (element: T, index: number) => boolean): AsyncIterableQuery<T>;
Parameters
predicate
- (required) function to test for each element
Example
import { queryAsync } from 'itiriri-async';
queryAsync([1, 2, 3, 4, 5]).filter(elem => elem < 3).toArray(); // returns [1, 2]
queryAsync([1, 2, 3]).filter(elem > 10).toArray(); // returns []
filter
is a deferred method and is executed only when the result sequence is iterated.
Finds the first element that satisfies the specified predicate.
Syntax
find(predicate: (element: T, index: number) => boolean): Promise<T>;
Parameters
predicate
- (required) function to test for each element
If no element satisfies the predicate, returns undefined
.
Example
import { queryAsync } from 'itiriri-async';
queryAsync([1, 2, 3, 4, 5]).find(elem => elem % 2 === 0); // returns 2
queryAsync([1, 2, 3]).find(elem > 10); // returns undefined
Finds the first index at which a given element satisfies the specified predicate.
Syntax
findIndex(predicate: (element: T, index: number) => boolean): Promise<number>;
Parameters
predicate
- (required) function to test for each element
If no element satisfies the predicate, returns -1
.
Example
import { queryAsync } from 'itiriri-async';
queryAsync([7, 12, 15]).findIndex(elem => elem > 10 && elem < 15); // returns 1
queryAsync([1, 2, 3]).findIndex(elem > 10); // returns -1
Finds the last element that satisfies the specified predicate.
Syntax
findLast(predicate: (element: T, index: number) => boolean): Promise<T>;
Parameters
predicate
- (required) function to test for each element
If no element satisfies the predicate, returns undefined
.
Example
import { queryAsync } from 'itiriri-async';
queryAsync([11, 7, 21]).findLast(elem => elem > 10); // returns 21
queryAsync([1, 2, 3]).findLast(elem > 10); // returns undefined
Finds the last index at which a given element satisfies the specified predicate.
Syntax
findLastIndex(predicate: (element: T, index: number) => boolean): Promise<number>;
Parameters
predicate
- (required) function to test for each element
If not present, returns -1.
Example
import { queryAsync } from 'itiriri-async';
queryAsync([11, 7, 21]).findLastIndex(elem => elem > 10); // returns 2
queryAsync([1, 2, 3]).findLastIndex(elem > 10); // returns -1
Returns the first element in a sequence.
Syntax
first(): Promise<T>;
For an empty sequence returns undefined
.
Example
import { queryAsync } from 'itiriri-async';
queryAsync(['a', 'b', 'c']).first(); // returns 'a'
queryAsync([]).first(); // returns undefined
Returns a sequence with all sub-sequences concatenated.
Syntax
flat<T>(): AsyncIterable<T>;
Example
import { queryAsync } from 'itiriri-async';
queryAsync([{value: [1, 2], {values: [7, 9]}]).flat(elem => elem.value).toArray();
// returns [1, 2, 7, 9]
flat
is a deferred method and is executed only when the result sequence is iterated.
Runs through every element and applies a given function.
Syntax
forEach(action: (element: T, index: number) => void): Promise<void>;
Parameters
action
- (required) function to apply on each element
Example
import { queryAsync } from 'itiriri-async';
queryAsync([1, 2, 3]).forEach(elem => console.log(elem));
// 1
// 2
// 3
Returns a sequence of correlated elements where each element from the current sequence is matched with zero or more elements from the other sequence.
Syntax
groupJoin<TKey, TRight, TResult>(
other: Iterable<TRight>,
leftKeySelector: (element: T, index: number) => TKey,
rightKeySelector: (element: TRight, index: number) => TKey,
joinSelector: (left: T, right: TRight[]) => TResult,
): AsyncIterableQuery<TResult>;
Parameters
other
- (required) sequence to joinleftKeySelector
- (required) function that provides the key of each element from source sequencerightKeySelector
- (required) function that provides the key of each element from joined sequencejoinSelector
- (required) a transformation function to apply on each joined element with group
The joinSelector
function is called on each element from the source sequence and the array of matched
elements from the joined sequence.
When an element from the source sequence doesn't match with any of the elements from the joined sequence,
the joinSelector
function will be called with an empty array.
Example
import { queryAsync } from 'itiriri-async';
const books = [
{title: 'Clean code', categoryId: 1 },
{title: 'Code complete', categoryId: 1},
{title: 'Scrum', categoryId: 2},
];
const categories = [
{id: 1, name: 'CS'},
{id: 2, name: 'Agile'},
];
queryAsync(categories).groupJoin(
books,
category => category.id,
book => book.categoryId,
(category, books) => ({ category: category.name, books: books.map(b => b.title) })
).toArray();
// [
// {category: 'CS', books: ['Clean code', 'Code complete']},
// {category: 'Agile'}, books: ['Scrum']
// ]
groupJoin
is a deferred method and is executed only when the result sequence is iterated.
Determines whether the sequence includes a certain element.
Syntax
includes(element: T): Promise<boolean>;
includes(element: T, fromIndex: number): Promise<boolean>;
Parameters
element
- (required) the element to search forfromIndex
- (optional) starting index, defaults to0
includes
uses triple equals ===
to compare elements.
Example
import { queryAsync } from 'itiriri-async';
queryAsync([1, 2, 3]).includes(2); // returns true
queryAsync([1, 2, 3]).includes(0); // returns false
Returns the first (zero-based) index at which a given element can be found.
Syntax
indexOf(element: T): Promise<number>;
indexOf(element: T, fromIndex: number): Promise<number>;
Parameters
element
- (required) the element to search forfromIndex
- (optional) starting index, defaults to0
When an element is not found, returns -1.
indexOf
uses triple equals ===
to compare elements.
Example
import { queryAsync } from 'itiriri-async';
queryAsync(['a', 'b', 'c']).indexOf('c'); // returns 2
queryAsync(['a', 'b', 'c']).indexOf('x'); // returns -1
Returns a set intersection with a given sequence.
Syntax
intersect(others: Iterable<T>): AsyncIterableQuery<T>;
intersect<S>(other: Iterable<T>, selector: (element: T) => S): AsyncIterableQuery<T>;
Parameters
other
- (required) the sequence to intersect withselector
- (optional) a value transformer function to be used for comparisons
Example
import { queryAsync } from 'itiriri-async';
queryAsync([1, 2, 3]]).intersect([2, 3, 4]).toArray(); // returns [2, 3]
queryAsync([{id: 1, name: 'Alice'}, {id: 2, name: 'Bob'})
.intersect([{id: 3, name: 'David'}, {id: 1, name: 'Alice'}], elem => elem.id)
.toArray(); // returns [{id: 1, name: 'Alice'}]
intersect
is a deferred method and is executed only when the result sequence is iterated.
Returns a sequence of correlated elements transformation that match a given key.
Syntax
join<TKey, TRight, TResult>(
other: Iterable<TRight>,
leftKeySelector: (element: T, index: number) => TKey,
rightKeySelector: (element: TRight, index: number) => TKey,
joinSelector: (left: T, right: TRight) => TResult,
): AsyncIterableQuery<TResult>;
Parameters
other
- (required) sequence to joinleftKeySelector
- (required) function that provides the key of each element from source sequencerightKeySelector
- (required) function that provides the key of each element from joined sequencejoinSelector
- (required) a transformation function to apply on each matched tuple
The join
method works as an sql inner join.
Example
import { queryAsync } from 'itiriri-async';
queryAsync([1, 2, 3])
.join([2, 3, 4], n => n, n => n, (a, b) => `${a}-${b}`)
.toArray();
// returns ['2-2', '3-3']
queryAsync([{countryId: 1, code: '+1'}, {countryId: 2, code: '+44'}]])
.join(
[{ id: 1, country: 'US' }, {id: 3, country: 'MD'}],
left => left.countryId,
right => right.id,
(left, right) => ({country: right.country, code: left.code}))
.toArray();
// returns [{country: 'US', code: '+1'}]
join
is a deferred method and is executed only when the result sequence is iterated.
Returns a sequence of keys for each index in the source sequence.
Syntax
keys(): AsyncIterableQuery<number>;
Example
import { queryAsync } from 'itiriri-async';
queryAsync(['a', 'b', 'c']).keys().toArray(); // returns [0, 1, 2]
keys
is a deferred method and is executed only when the result sequence is iterated.
Returns the last element in a sequence.
Syntax
last(): Promise<T>;
For an empty sequence returns undefined
.
Example
import { queryAsync } from 'itiriri-async';
queryAsync(['a', 'b', 'c']).last(); // returns 'c'
queryAsync([]).last(); // returns undefined
Returns the last index at which a given element can be found.
Syntax
lastIndexOf(element: T): Promise<number>;
lastIndexOf(element: T, fromIndex: number): Promise<number>;
Parameters
element
- (required) the element to search forfromIndex
- (optional) starting index, defaults to0
When an element is not found, returns -1.
lastIndexOf
uses triple equals ===
to compare elements.
Example
import { queryAsync } from 'itiriri-async';
queryAsync(['a', 'c', 'c']).lastIndexOf('c'); // returns 2
queryAsync(['a', 'b', 'c']).lastIndexOf('x'); // returns -1
Returns a sequence of correlated elements transformation that match a given key.
Syntax
leftJoin<TKey, TRight, TResult>(
other: Iterable<TRight>,
leftKeySelector: (element: T, index: number) => TKey,
rightKeySelector: (element: TRight, index: number) => TKey,
joinSelector: (left: T, right?: TRight) => TResult,
): AsyncIterableQuery<TResult>;
Parameters
other
- (required) sequence to joinleftKeySelector
- (required) function that provides the key of each element from source sequencerightKeySelector
- (required) function that provides the key of each element from joined sequencejoinSelector
- (required) a transformation function to apply on each matched tuple
The leftJoin
method works as an sql left join.
When an element from the left sequence doesn't match with any of the elements from the right sequence,
the joinSelector
function is called with an undefined
right value.
Example
import { queryAsync } from 'itiriri-async';
queryAsync([1, 2, 3])
.leftJoin([2, 3, 4, 2], n => n, n => n, (a, b) => `${a}-${b || '#'}`)
.toArray();
// returns ['1-#', '2-2', '2-2', '3-3']
queryAsync([{book: 'History', owner: 3}, {book: 'Math', owner: 2}, {book: 'Art'}]])
.leftJoin(
[{id: 1, name: 'Alice'}, {id: 2, name: 'Bob'}, {id: 3, name: 'Eve'}],
left => left.owner,
right => right.id,
(left, right) => ({book: left.book, owner: right && right.owner || '--'}))
.toArray();
// returns [
// {book: 'History', owner: 'Eve'},
// {book: 'Math', owner: 'Bob'},
// {book: 'Art', owner: '--'}]
leftJoin
is a deferred method and is executed only when the result sequence is iterated.
Returns the number of elements in a sequence.
Syntax
length(): Promise<number>;
length(predicate: (element: T, index: number) => boolean): <number>;
Parameters
predicate
- (optional) a function to count only the elements that match the predicate
Example
import { queryAsync } from 'itiriri-async';
queryAsync([1, 2, 3, 4, 5]).length(); // returns 5
queryAsync([1, 2, 3, 4, 5]).length(elem => elem > 2); // returns 3
Returns a sequence of transformed values.
Syntax
map<S>(selector: (element: T, index: number) => S): AsyncIterableQuery<S>;
Parameters
selector
- (required) a value transformer function to apply to each element
Example
import { queryAsync } from 'itiriri-async';
queryAsync([1, 2, 3]).map(elem => elem * 10).toArray(); // returns [10, 20, 30]
map
is a deferred method and is executed only when the result sequence is iterated.
Returns the maximum element in a sequence.
Syntax
max(): Promise<T>;
max(compareFn: (a: T, b: T) => number): Promise<T>;
Parameters
compareFn
- (optional) a comparer function that compares two elements from a sequence and returns:-1
whena
is less thanb
1
whena
is greaterb
0
whena
equals tob
If sequence is empty, returns undefined
.
Example
import { queryAsync } from 'itiriri-async';
queryAsync([1, 2, 3]).max(); // returns 3
queryAsync([]).max(); // returns undefined
queryAsync([7, 3, 11, 5]).max((a, b) => (1 / a) - (1 / b)); // returns 3
Returns the minimum element in a sequence.
Syntax
min(): Promise<T>;
min(compareFn: (a: T, b: T) => number): Promise<T>;
Parameters
compareFn
- (optional) a comparer function that compares two elements from a sequence and returns:-1
whena
is less thanb
1
whena
is greaterb
0
whena
equals tob
If sequence is empty, returns undefined
.
Example
import { queryAsync } from 'itiriri-async';
queryAsync([1, 2, 3]).min(); // returns 1
queryAsync([]).min(); // returns undefined
queryAsync([7, 3, 11, 5]).min((a, b) => (1 / a) - (1 / b)); // returns 11
Returns the element at a specified index.
Syntax
nth(index: number): Promise<T>;
Parameters
index
- (required) zero based index at which to get the element
For a negative index returns the element from the end of the sequence.
If index is out of the range, returns undefined
.
Example
import { queryAsync } from 'itiriri-async';
queryAsync(['a', 'b', 'c', 'd']).nth(2) // returns 'c'
queryAsync(['a', 'b', 'c', 'd']).nth(-1) // returns 'd'
queryAsync(['a', 'b', 'c', 'd']).nth(10) // returns undefined
Returns a sequence with given elements at the beginning.
Syntax
prepend(other: AsyncIterable<T> | T): AsyncIterableQuery<T>;
Parameters
other
- (required) the sequence to be added at the beginning
Example
import { queryAsync } from 'itiriri-async';
queryAsync([1, 2, 3]).prepend([9, 10]).toArray(); // returns [1, 2, 3, 9, 10]
prepend
is a deferred method and is executed only when the result sequence is iterated.
Applies a function against an accumulator and each element (from left to right) to reduce it to a single value.
Syntax
reduce(
callback: (accumulator: T, current: T, index: number) => T,
): Promise<any>;
reduce<S>(
callback: (accumulator: S, current: T, index: number) => S,
initialValue: S,
): Promise<any>;
Parameters
callback
- (required) function to execute on each element in the sequence, taking three argumentsaccumulator
the accumulator accumulates the callback's return values;current
the current element being processed;currentIndex
the index of the current element being processed;
initialValue
- (optional) value to use as the first argument to the first call of thecallback
Calling reduce
on an empty sequence without an initial value throws an error.
Example
import { queryAsync } from 'itiriri-async';
queryAsync([ 1, 2, 42, 0 ]).reduce((acc, elem) => Math.max(acc, elem)); // returns 42
queryAsync([ 1, 2, 3 ]).reduce((acc, elem) => acc + elem, 10); // returns 16
Skips the specified number of elements from the beginning of sequence and returns the remaining ones.
Syntax
skip(count: number): AsyncIterableQuery<T>;
Parameters
count
- (required) number of elements to skip
When count is greater than actual number of elements, results in an empty sequence.
Accepts also a negative count, in which case skips the elements from the end of the sequence.
Example
import { queryAsync } from 'itiriri-async';
queryAsync([1, 2, 3, 4, 5]).skip(2).toArray(); // [3, 4, 5]
queryAsync([1, 2, 3, 4, 5]).skip(10).toArray(); // []
queryAsync([1, 2, 3, 4, 5]).skip(-2).toArray(); // [1, 2, 3]
skip
is a deferred method and is executed only when the result sequence is iterated.
Returns a sequence that represents the range of elements from start to end.
Syntax
slice(start: number, end: number): AsyncIterableQuery<T>;
Parameters
start
- (required) zero-based index at which to begin extractionend
- (required) zero-based index before which to end extraction.
The end
index is not included in the result.
Example
import { queryAsync } from 'itiriri-async';
queryAsync([1, 2, 3, 4, 5]).slice(1, 3).toArray(); // returns [2, 3]
slice
is a deferred method and is executed only when the result sequence is iterated.
Tests whether at least one element passes the predicate.
Syntax
some(predicate: (element: T, index: number) => boolean): Promise<boolean>;
Parameters
predicate
- (required) function to test for each element
Example
import { queryAsync } from 'itiriri-async';
queryAsync([1, 2, 3, 42, 5]).some(elem => elem > 40); // returns true
queryAsync([1, 2, 3, 42, 5]).some(elem => elem < 0); // returns false
Returns the sum of all elements.
Syntax
sum(): number;
sum(selector: (element: T, index: number) => number): Promise<number>;
Parameters
selector
- (optional) a value transformer function to apply to each element
Optionally, a function can be provided to apply a transformation and map each element to a value.
Example
import { queryAsync } from 'itiriri-async';
queryAsync([1, 2, 3]).sum(); // returns 6
queryAsync([{value: 1}, {value: 2}]).sum(elem => elem.value); // returns 3
Returns a specified number of elements from the beginning of sequence.
Syntax
take(count: number): AsyncIterableQuery<T>;
Parameters
count
- (required) number of elements to take
If a negative count is specified, returns elements from the end of the sequence.
Example
import { queryAsync } from 'itiriri-async';
queryAsync([1, 2, 3]).take(2); // returns [1, 2]
queryAsync([1, 2, 3]).take(-2); // returns [2, 3]
queryAsync([1, 2, 3]).take(10); // returns [1, 2, 3]
take
is a deferred method and is executed only when the result sequence is iterated.
Returns a set union with a given sequence.
Syntax
union(other: AsyncIterable<T>): AsyncIterableQuery<T>;
union<S>(other: AsyncIterable<T>, selector: (element: T) => S): AsyncIterableQuery<T>;
Parameters
other
- (required) the sequence to join withselector
- (optional) a value transformer function to be used for comparisons
Example
import { queryAsync } from 'itiriri-async';
queryAsync([1, 2, 3]]).union([2, 3, 4]).toArray(); // returns [1, 2, 3, 4]
queryAsync([{id: 1, name: 'Alice'}, {id: 2, name: 'Bob'})
.union([{id: 3, name: 'David'}, {id: 1, name: 'Alice'}], elem => elem.id)
.toArray();
// returns [
// {id: 1, name: 'Alice'},
// {id: 2, name: 'Bob'},
// {id: 3, name: 'David'}]
union
is a deferred method and is executed only when the result sequence is iterated.
Returns a sequence of values for each index in the source sequence.
Syntax
values(): AsyncIterableQuery<T>;
Example
import { queryAsync } from 'itiriri-async';
queryAsync([1, 2, 3]]).values().toArray(); // returns [1, 2, 3]
values
is a deferred method and is executed only when the result sequence is iterated.
iterator iterable async filter map query collections deferred lazy