itertools-ts
Version:
Extended itertools port for TypeScript and JavaScript. Provides a huge set of functions for working with iterable collections (including async ones)
1,107 lines • 36.5 kB
JavaScript
var __asyncValues = (this && this.__asyncValues) || function (o) {
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
var m = o[Symbol.asyncIterator], i;
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
};
var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }
var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
var g = generator.apply(thisArg, _arguments || []), i, q = [];
return i = Object.create((typeof AsyncIterator === "function" ? AsyncIterator : Object).prototype), verb("next"), verb("throw"), verb("return", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i;
function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; }
function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } }
function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
function fulfill(value) { resume("next", value); }
function reject(value) { resume("throw", value); }
function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
};
import { toArray, toArrayAsync, toAsyncIterable, toIterable, } from "./transform";
import { InvalidArgumentError } from "./exceptions";
import { isAsyncIterable, isIterable, isIterator, isString } from "./summary";
import { distinct, distinctAsync } from "./set";
import { zip, zipAsync } from "./multi";
/**
* Map a function onto every element of the iteration.
*
* @param data
* @param mapper
*/
export function* map(data, mapper) {
for (const datum of toIterable(data)) {
yield mapper(datum);
}
}
/**
* Map a function onto every element of the iteration for async collections.
*
* Mapper may be also async.
*
* @param data
* @param mapper
*/
export function mapAsync(data, mapper) {
return __asyncGenerator(this, arguments, function* mapAsync_1() {
var _a, e_1, _b, _c;
try {
for (var _d = true, _e = __asyncValues(toAsyncIterable(data)), _f; _f = yield __await(_e.next()), _a = _f.done, !_a; _d = true) {
_c = _f.value;
_d = false;
const datum = _c;
yield yield __await(yield __await(mapper(datum)));
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (!_d && !_a && (_b = _e.return)) yield __await(_b.call(_e));
}
finally { if (e_1) throw e_1.error; }
}
});
}
/**
* Compress an iterable by filtering out data that is not selected.
*
* Selectors indicate which data. True value selects item. False value filters out data.
*
* @param data
* @param selectors
*/
export function* compress(data, selectors) {
for (const [datum, selector] of zip(data, selectors)) {
if (selector) {
yield datum;
}
}
}
/**
* Compress an async iterable by filtering out data that is not selected.
*
* Selectors indicate which data. True value selects item. False value filters out data.
*
* Selectors may be also async collection.
*
* @param data
* @param selectors
*/
export function compressAsync(data, selectors) {
return __asyncGenerator(this, arguments, function* compressAsync_1() {
var _a, e_2, _b, _c;
try {
for (var _d = true, _e = __asyncValues(zipAsync(data, selectors)), _f; _f = yield __await(_e.next()), _a = _f.done, !_a; _d = true) {
_c = _f.value;
_d = false;
const [datum, selector] = _c;
if (selector) {
yield yield __await(datum);
}
}
}
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
if (!_d && !_a && (_b = _e.return)) yield __await(_b.call(_e));
}
finally { if (e_2) throw e_2.error; }
}
});
}
/**
* Drop elements from the iterable while the predicate function is true.
*
* Once the predicate function returns false once, all remaining elements are returned.
*
* @param data
* @param predicate
*/
export function* dropWhile(data, predicate) {
let drop = true;
for (const datum of toIterable(data)) {
if (drop) {
if (!predicate(datum)) {
drop = false;
yield datum;
continue;
}
continue;
}
yield datum;
}
}
/**
* Drop elements from the async iterable while the predicate function is true.
*
* Once the predicate function returns false once, all remaining elements are returned.
*
* Predicate may be also async.
*
* @param data
* @param predicate
*/
export function dropWhileAsync(data, predicate) {
return __asyncGenerator(this, arguments, function* dropWhileAsync_1() {
var _a, e_3, _b, _c;
let drop = true;
try {
for (var _d = true, _e = __asyncValues(toAsyncIterable(data)), _f; _f = yield __await(_e.next()), _a = _f.done, !_a; _d = true) {
_c = _f.value;
_d = false;
const datum = _c;
if (drop) {
if (!(yield __await(predicate(datum)))) {
drop = false;
yield yield __await(datum);
continue;
}
continue;
}
yield yield __await(datum);
}
}
catch (e_3_1) { e_3 = { error: e_3_1 }; }
finally {
try {
if (!_d && !_a && (_b = _e.return)) yield __await(_b.call(_e));
}
finally { if (e_3) throw e_3.error; }
}
});
}
/**
* Return elements from the iterable as long as the predicate is true.
*
* If no predicate is provided, the boolean value of the data is used.
*
* @param data
* @param predicate
*/
export function* takeWhile(data, predicate) {
for (const datum of toIterable(data)) {
if (predicate(datum)) {
yield datum;
}
else {
break;
}
}
}
/**
* Return elements from the async iterable as long as the predicate is true.
*
* Predicate may be also async.
*
* If no predicate is provided, the boolean value of the data is used.
*
* @param data
* @param predicate
*/
export function takeWhileAsync(data, predicate) {
return __asyncGenerator(this, arguments, function* takeWhileAsync_1() {
var _a, e_4, _b, _c;
try {
for (var _d = true, _e = __asyncValues(toAsyncIterable(data)), _f; _f = yield __await(_e.next()), _a = _f.done, !_a; _d = true) {
_c = _f.value;
_d = false;
const datum = _c;
if (yield __await(predicate(datum))) {
yield yield __await(datum);
}
else {
break;
}
}
}
catch (e_4_1) { e_4 = { error: e_4_1 }; }
finally {
try {
if (!_d && !_a && (_b = _e.return)) yield __await(_b.call(_e));
}
finally { if (e_4) throw e_4.error; }
}
});
}
/**
* Repeat an item.
*
* @param item
* @param repetitions
*/
export function* repeat(item, repetitions) {
if (repetitions < 0) {
throw new InvalidArgumentError(`Number of repetitions cannot be negative: ${repetitions}`);
}
for (let i = repetitions; i > 0; --i) {
yield item;
}
}
/**
* Repeat an item given as promise.
*
* @param item
* @param repetitions
*/
export function repeatAsync(item, repetitions) {
return __asyncGenerator(this, arguments, function* repeatAsync_1() {
if (repetitions < 0) {
throw new InvalidArgumentError(`Number of repetitions cannot be negative: ${repetitions}`);
}
const value = yield __await(item);
for (let i = repetitions; i > 0; --i) {
yield yield __await(value);
}
});
}
/**
* Returns a new collection formed by applying a given callback mapper function to each element
* of the given collection, and then flattening the result by one level.
*
* The mapper function can return scalar or collections as a result.
*
* @param data
* @param mapper
*/
export function* flatMap(data, mapper) {
for (const datum of toIterable(data)) {
const unflattened = mapper(datum, mapper);
if (isIterable(unflattened)) {
for (const flattenedItem of toIterable(unflattened)) {
yield flattenedItem;
}
}
else {
yield unflattened;
}
}
}
/**
* Returns a new async collection formed by applying a given callback mapper function to each element
* of the given async collection, and then flattening the result by one level.
*
* The mapper function can return scalar or collections as a result.
*
* The mapper function may be also async.
*
* @param data
* @param mapper
*/
export function flatMapAsync(data, mapper) {
return __asyncGenerator(this, arguments, function* flatMapAsync_1() {
var _a, e_5, _b, _c, _d, e_6, _e, _f;
try {
for (var _g = true, _h = __asyncValues(toAsyncIterable(data)), _j; _j = yield __await(_h.next()), _a = _j.done, !_a; _g = true) {
_c = _j.value;
_g = false;
const datum = _c;
const unflattened = yield __await(mapper(datum, mapper));
if (isIterable(unflattened) || isAsyncIterable(unflattened)) {
try {
for (var _k = true, _l = (e_6 = void 0, __asyncValues(toAsyncIterable(unflattened))), _m; _m = yield __await(_l.next()), _d = _m.done, !_d; _k = true) {
_f = _m.value;
_k = false;
const flattenedItem = _f;
yield yield __await(flattenedItem);
}
}
catch (e_6_1) { e_6 = { error: e_6_1 }; }
finally {
try {
if (!_k && !_d && (_e = _l.return)) yield __await(_e.call(_l));
}
finally { if (e_6) throw e_6.error; }
}
}
else {
yield yield __await(unflattened);
}
}
}
catch (e_5_1) { e_5 = { error: e_5_1 }; }
finally {
try {
if (!_g && !_a && (_b = _h.return)) yield __await(_b.call(_h));
}
finally { if (e_5) throw e_5.error; }
}
});
}
/**
* Flatten an iterable by a number of dimensions.
*
* Ex: [[1, 2], [3, 4], 5] => [1, 2, 3, 4, 5] // Flattened by one dimension
*
* @param data
* @param dimensions
*/
export function* flatten(data, dimensions = Infinity) {
if (dimensions < 1) {
for (let datum of toIterable(data)) {
if (data instanceof Map) {
datum = datum[1];
}
yield datum;
}
return;
}
for (let datum of toIterable(data)) {
if (data instanceof Map) {
datum = datum[1];
}
if ((isIterable(datum) || isIterator(datum)) && !isString(datum)) {
for (const subDatum of flatten(datum, dimensions - 1)) {
yield subDatum;
}
}
else {
yield datum;
}
}
}
/**
* Flatten an async iterable by a number of dimensions.
*
* Ex: [[1, 2], [3, 4], 5] => [1, 2, 3, 4, 5] // Flattened by one dimension
*
* @param data
* @param dimensions
*/
export function flattenAsync(data_1) {
return __asyncGenerator(this, arguments, function* flattenAsync_1(data, dimensions = Infinity) {
var _a, e_7, _b, _c, _d, e_8, _e, _f, _g, e_9, _h, _j;
if (dimensions < 1) {
try {
for (var _k = true, _l = __asyncValues(toAsyncIterable(data)), _m; _m = yield __await(_l.next()), _a = _m.done, !_a; _k = true) {
_c = _m.value;
_k = false;
let datum = _c;
if (data instanceof Map) {
datum = datum[1];
}
yield yield __await(datum);
}
}
catch (e_7_1) { e_7 = { error: e_7_1 }; }
finally {
try {
if (!_k && !_a && (_b = _l.return)) yield __await(_b.call(_l));
}
finally { if (e_7) throw e_7.error; }
}
return yield __await(void 0);
}
try {
for (var _o = true, _p = __asyncValues(toAsyncIterable(data)), _q; _q = yield __await(_p.next()), _d = _q.done, !_d; _o = true) {
_f = _q.value;
_o = false;
let datum = _f;
if (data instanceof Map) {
datum = datum[1];
}
if ((isAsyncIterable(datum) || isIterable(datum) || isIterator(datum)) && !isString(datum)) {
try {
for (var _r = true, _s = (e_9 = void 0, __asyncValues(flattenAsync(datum, dimensions - 1))), _t; _t = yield __await(_s.next()), _g = _t.done, !_g; _r = true) {
_j = _t.value;
_r = false;
const subDatum = _j;
yield yield __await(subDatum);
}
}
catch (e_9_1) { e_9 = { error: e_9_1 }; }
finally {
try {
if (!_r && !_g && (_h = _s.return)) yield __await(_h.call(_s));
}
finally { if (e_9) throw e_9.error; }
}
}
else {
yield yield __await(datum);
}
}
}
catch (e_8_1) { e_8 = { error: e_8_1 }; }
finally {
try {
if (!_o && !_d && (_e = _p.return)) yield __await(_e.call(_p));
}
finally { if (e_8) throw e_8.error; }
}
});
}
/**
* Filter out elements from the iterable only returning elements where there predicate function is true.
*
* @param data
* @param predicate
*/
export function* filter(data, predicate) {
for (const datum of toIterable(data)) {
if (predicate(datum)) {
yield datum;
}
}
}
/**
* Filter out elements from the async iterable only returning elements where there predicate function is true.
*
* Predicate may be also async.
*
* @param data
* @param predicate
*/
export function filterAsync(data, predicate) {
return __asyncGenerator(this, arguments, function* filterAsync_1() {
var _a, e_10, _b, _c;
try {
for (var _d = true, _e = __asyncValues(toAsyncIterable(data)), _f; _f = yield __await(_e.next()), _a = _f.done, !_a; _d = true) {
_c = _f.value;
_d = false;
const datum = _c;
if (yield __await(predicate(datum))) {
yield yield __await(datum);
}
}
}
catch (e_10_1) { e_10 = { error: e_10_1 }; }
finally {
try {
if (!_d && !_a && (_b = _e.return)) yield __await(_b.call(_e));
}
finally { if (e_10) throw e_10.error; }
}
});
}
/**
* Return overlapped chunks of elements from given collection.
*
* Chunk size must be at least 1.
*
* Overlap size must be less than chunk size.
*
* @param data
* @param chunkSize
* @param overlapSize
* @param includeIncompleteTail
*/
export function* chunkwiseOverlap(data, chunkSize, overlapSize, includeIncompleteTail = true) {
if (chunkSize < 1) {
throw new InvalidArgumentError(`Chunk size must be ≥ 1. Got ${chunkSize}`);
}
if (overlapSize >= chunkSize) {
throw new InvalidArgumentError("Overlap size must be less than chunk size");
}
let chunk = [];
let isLastIterationYielded = false;
for (const datum of toIterable(data)) {
isLastIterationYielded = false;
chunk.push(datum);
if (chunk.length === chunkSize) {
yield chunk;
chunk = chunk.slice(chunkSize - overlapSize);
isLastIterationYielded = true;
}
}
if (!isLastIterationYielded && chunk.length > 0 && includeIncompleteTail) {
yield chunk;
}
}
/**
* Return overlapped chunks of elements from given async collection.
*
* Chunk size must be at least 1.
*
* Overlap size must be less than chunk size.
*
* @param data
* @param chunkSize
* @param overlapSize
* @param includeIncompleteTail
*/
export function chunkwiseOverlapAsync(data_1, chunkSize_1, overlapSize_1) {
return __asyncGenerator(this, arguments, function* chunkwiseOverlapAsync_1(data, chunkSize, overlapSize, includeIncompleteTail = true) {
var _a, e_11, _b, _c;
if (chunkSize < 1) {
throw new InvalidArgumentError(`Chunk size must be ≥ 1. Got ${chunkSize}`);
}
if (overlapSize >= chunkSize) {
throw new InvalidArgumentError("Overlap size must be less than chunk size");
}
let chunk = [];
let isLastIterationYielded = false;
try {
for (var _d = true, _e = __asyncValues(toAsyncIterable(data)), _f; _f = yield __await(_e.next()), _a = _f.done, !_a; _d = true) {
_c = _f.value;
_d = false;
const datum = _c;
isLastIterationYielded = false;
chunk.push(datum);
if (chunk.length === chunkSize) {
yield yield __await(chunk);
chunk = chunk.slice(chunkSize - overlapSize);
isLastIterationYielded = true;
}
}
}
catch (e_11_1) { e_11 = { error: e_11_1 }; }
finally {
try {
if (!_d && !_a && (_b = _e.return)) yield __await(_b.call(_e));
}
finally { if (e_11) throw e_11.error; }
}
if (!isLastIterationYielded && chunk.length > 0 && includeIncompleteTail) {
yield yield __await(chunk);
}
});
}
/**
* Return chunks of elements from given collection.
*
* Chunk size must be at least 1.
*
* @param data
* @param chunkSize
*/
export function* chunkwise(data, chunkSize) {
for (const chunk of chunkwiseOverlap(data, chunkSize, 0)) {
yield chunk;
}
}
/**
* Return chunks of elements from given async collection.
*
* Chunk size must be at least 1.
*
* @param data
* @param chunkSize
*/
export function chunkwiseAsync(data, chunkSize) {
return __asyncGenerator(this, arguments, function* chunkwiseAsync_1() {
var _a, e_12, _b, _c;
try {
for (var _d = true, _e = __asyncValues(chunkwiseOverlapAsync(data, chunkSize, 0)), _f; _f = yield __await(_e.next()), _a = _f.done, !_a; _d = true) {
_c = _f.value;
_d = false;
const chunk = _c;
yield yield __await(chunk);
}
}
catch (e_12_1) { e_12 = { error: e_12_1 }; }
finally {
try {
if (!_d && !_a && (_b = _e.return)) yield __await(_b.call(_e));
}
finally { if (e_12) throw e_12.error; }
}
});
}
/**
* Return pairs of elements from given collection.
*
* Returns empty generator if given collection contains less than 2 elements.
*
* @param data
*/
export function* pairwise(data) {
const chunked = chunkwiseOverlap(data, 2, 1, false);
for (const chunk of chunked) {
yield chunk;
}
}
/**
* Return pairs of elements from given async collection.
*
* Returns empty generator if given collection contains less than 2 elements.
*
* @param data
*/
export function pairwiseAsync(data) {
return __asyncGenerator(this, arguments, function* pairwiseAsync_1() {
var _a, e_13, _b, _c;
const chunked = chunkwiseOverlapAsync(data, 2, 1, false);
try {
for (var _d = true, chunked_1 = __asyncValues(chunked), chunked_1_1; chunked_1_1 = yield __await(chunked_1.next()), _a = chunked_1_1.done, !_a; _d = true) {
_c = chunked_1_1.value;
_d = false;
const chunk = _c;
yield yield __await(chunk);
}
}
catch (e_13_1) { e_13 = { error: e_13_1 }; }
finally {
try {
if (!_d && !_a && (_b = chunked_1.return)) yield __await(_b.call(chunked_1));
}
finally { if (e_13) throw e_13.error; }
}
});
}
/**
* Limit iteration to a max size limit.
*
* @param data
* @param count ≥ 0, max count of iteration
*/
export function* limit(data, count) {
if (count < 0) {
throw new InvalidArgumentError(`Limit must be ≥ 0. Got ${count}`);
}
let i = 0;
for (const datum of toIterable(data)) {
if (i >= count) {
return;
}
yield datum;
++i;
}
}
/**
* Limit iteration of async iterable to a max size limit.
*
* @param data
* @param count ≥ 0, max count of iteration
*/
export function limitAsync(data, count) {
return __asyncGenerator(this, arguments, function* limitAsync_1() {
var _a, e_14, _b, _c;
if (count < 0) {
throw new InvalidArgumentError(`Limit must be ≥ 0. Got ${count}`);
}
let i = 0;
try {
for (var _d = true, _e = __asyncValues(toAsyncIterable(data)), _f; _f = yield __await(_e.next()), _a = _f.done, !_a; _d = true) {
_c = _f.value;
_d = false;
const datum = _c;
if (i >= count) {
return yield __await(void 0);
}
yield yield __await(datum);
++i;
}
}
catch (e_14_1) { e_14 = { error: e_14_1 }; }
finally {
try {
if (!_d && !_a && (_b = _e.return)) yield __await(_b.call(_e));
}
finally { if (e_14) throw e_14.error; }
}
});
}
/**
* Enumerates items of given collection.
*
* Ex: ['a', 'b', 'c'] => [[0, 'a'], [1, 'b'], [2, 'c']]
*
* @param data
*/
export function* enumerate(data) {
let i = 0;
for (const datum of toIterable(data)) {
yield [i++, datum];
}
}
/**
* Enumerates items of given async collection.
*
* Ex: ['a', 'b', 'c'] => [[0, 'a'], [1, 'b'], [2, 'c']]
*
* @param data
*/
export function enumerateAsync(data) {
return __asyncGenerator(this, arguments, function* enumerateAsync_1() {
var _a, e_15, _b, _c;
let i = 0;
try {
for (var _d = true, _e = __asyncValues(toAsyncIterable(data)), _f; _f = yield __await(_e.next()), _a = _f.done, !_a; _d = true) {
_c = _f.value;
_d = false;
const datum = _c;
yield yield __await([i++, datum]);
}
}
catch (e_15_1) { e_15 = { error: e_15_1 }; }
finally {
try {
if (!_d && !_a && (_b = _e.return)) yield __await(_b.call(_e));
}
finally { if (e_15) throw e_15.error; }
}
});
}
/**
* Extract a slice of the collection.
*
* @param data
* @param start
* @param count
* @param step
*
* @throws InvalidArgumentError if `start` or `count` are negative or if `step` is not positive.
*/
export function* slice(data, start = 0, count, step = 1) {
if (start < 0) {
throw new InvalidArgumentError("Parameter 'start' cannot be negative");
}
if (count !== undefined && count < 0) {
throw new InvalidArgumentError("Parameter 'count' cannot be negative");
}
if (step <= 0) {
throw new InvalidArgumentError("Parameter 'step' must be positive");
}
let index = 0;
let yielded = 0;
for (const datum of toIterable(data)) {
if (index++ < start || (index - start - 1) % step !== 0) {
continue;
}
if (yielded++ === count && count !== undefined) {
break;
}
yield datum;
}
}
/**
* Extract a slice of the async collection.
*
* @param data
* @param start
* @param count
* @param step
*
* @throws InvalidArgumentError if `start` or `count` are negative or if `step` is not positive.
*/
export function sliceAsync(data_1) {
return __asyncGenerator(this, arguments, function* sliceAsync_1(data, start = 0, count, step = 1) {
var _a, e_16, _b, _c;
if (start < 0) {
throw new InvalidArgumentError("Parameter 'start' cannot be negative");
}
if (count !== undefined && count < 0) {
throw new InvalidArgumentError("Parameter 'count' cannot be negative");
}
if (step <= 0) {
throw new InvalidArgumentError("Parameter 'step' must be positive");
}
let index = 0;
let yielded = 0;
try {
for (var _d = true, _e = __asyncValues(toAsyncIterable(data)), _f; _f = yield __await(_e.next()), _a = _f.done, !_a; _d = true) {
_c = _f.value;
_d = false;
const datum = _c;
if (index++ < start || (index - start - 1) % step !== 0) {
continue;
}
if (yielded++ === count && count !== undefined) {
break;
}
yield yield __await(datum);
}
}
catch (e_16_1) { e_16 = { error: e_16_1 }; }
finally {
try {
if (!_d && !_a && (_b = _e.return)) yield __await(_b.call(_e));
}
finally { if (e_16) throw e_16.error; }
}
});
}
/**
* Iterates keys from the collection of key-value pairs.
*
* Ex: [[0, 'a'], [1, 'b'], [2, 'c']] => [0, 1, 2]
*
* @param collection
*/
export function* keys(collection) {
for (const [key] of toIterable(collection)) {
yield key;
}
}
/**
* Iterates keys from the async collection of key-value pairs.
*
* Ex: [[0, 'a'], [1, 'b'], [2, 'c']] => [0, 1, 2]
*
* @param collection
*/
export function keysAsync(collection) {
return __asyncGenerator(this, arguments, function* keysAsync_1() {
var _a, e_17, _b, _c;
try {
for (var _d = true, _e = __asyncValues(toAsyncIterable(collection)), _f; _f = yield __await(_e.next()), _a = _f.done, !_a; _d = true) {
_c = _f.value;
_d = false;
const [key] = _c;
yield yield __await(key);
}
}
catch (e_17_1) { e_17 = { error: e_17_1 }; }
finally {
try {
if (!_d && !_a && (_b = _e.return)) yield __await(_b.call(_e));
}
finally { if (e_17) throw e_17.error; }
}
});
}
/**
* Skip n elements in the iterable after optional offset.
*
* @param data
* @param count
* @param offset
*
* @throws InvalidArgumentError if `count` or `offset` is less then 0
*/
export function* skip(data, count, offset = 0) {
if (count < 0 || offset < 0) {
throw new InvalidArgumentError();
}
let skipped = -offset;
for (const datum of toIterable(data)) {
if (skipped < 0 || skipped >= count) {
yield datum;
}
++skipped;
}
}
/**
* Skip n elements in the async iterable after optional offset.
*
* @param data
* @param count
* @param offset
*
* @throws InvalidArgumentError if `count` or `offset` is less then 0
*/
export function skipAsync(data_1, count_1) {
return __asyncGenerator(this, arguments, function* skipAsync_1(data, count, offset = 0) {
var _a, e_18, _b, _c;
if (count < 0 || offset < 0) {
throw new InvalidArgumentError();
}
let skipped = -offset;
try {
for (var _d = true, _e = __asyncValues(toAsyncIterable(data)), _f; _f = yield __await(_e.next()), _a = _f.done, !_a; _d = true) {
_c = _f.value;
_d = false;
const datum = _c;
if (skipped < 0 || skipped >= count) {
yield yield __await(datum);
}
++skipped;
}
}
catch (e_18_1) { e_18 = { error: e_18_1 }; }
finally {
try {
if (!_d && !_a && (_b = _e.return)) yield __await(_b.call(_e));
}
finally { if (e_18) throw e_18.error; }
}
});
}
/**
* Iterates values from the collection of key-value pairs.
*
* Ex: [[0, 'a'], [1, 'b'], [2, 'c']] => ['a', 'b', 'c']
*
* @param collection
*/
export function* values(collection) {
for (const [, value] of toIterable(collection)) {
yield value;
}
}
/**
* Iterates values from the async collection of key-value pairs.
*
* Ex: [[0, 'a'], [1, 'b'], [2, 'c']] => ['a', 'b', 'c']
*
* @param collection
*/
export function valuesAsync(collection) {
return __asyncGenerator(this, arguments, function* valuesAsync_1() {
var _a, e_19, _b, _c;
try {
for (var _d = true, _e = __asyncValues(toAsyncIterable(collection)), _f; _f = yield __await(_e.next()), _a = _f.done, !_a; _d = true) {
_c = _f.value;
_d = false;
const [, value] = _c;
yield yield __await(value);
}
}
catch (e_19_1) { e_19 = { error: e_19_1 }; }
finally {
try {
if (!_d && !_a && (_b = _e.return)) yield __await(_b.call(_e));
}
finally { if (e_19) throw e_19.error; }
}
});
}
/**
* Group data by a common data element.
*
* Iterate pairs of group name and collection of grouped items.
*
* Collection of grouped items may be an array or an object (depends on presence of `itemKeyFunction` param).
*
* @param data
* @param groupKeyFunction - determines the key (or multiple keys) to group elements by.
* @param itemKeyFunction - (optional) determines the key of element in group.
*/
export function* groupBy(data, groupKeyFunction, itemKeyFunction) {
const groups = new Map();
const addGroup = (name) => {
if (!groups.has(name)) {
if (itemKeyFunction !== undefined) {
groups.set(name, {});
}
else {
groups.set(name, []);
}
}
};
for (const item of toIterable(data)) {
const group = groupKeyFunction(item);
const itemKey = itemKeyFunction !== undefined ? itemKeyFunction(item) : undefined;
const itemGroups = (isIterable(group) || isIterator(group)) && !isString(group)
? group
: [group];
for (const itemGroup of distinct(itemGroups)) {
addGroup(itemGroup);
if (itemKey === undefined) {
groups.get(itemGroup).push(item);
}
else {
groups.get(itemGroup)[itemKey] = item;
}
}
}
for (const group of groups) {
yield group;
}
}
/**
* Group async data by a common data element.
*
* Iterate pairs of group name and collection of grouped items.
*
* Collection of grouped items may be an array or an object (depends on presence of `itemKeyFunction` param).
*
* Functions `groupKeyFunction` and `itemKeyFunction` may be async.
*
* @param data
* @param groupKeyFunction - determines the key (or multiple keys) to group elements by.
* @param itemKeyFunction - (optional) determines the key of element in group.
*/
export function groupByAsync(data, groupKeyFunction, itemKeyFunction) {
return __asyncGenerator(this, arguments, function* groupByAsync_1() {
var _a, e_20, _b, _c, _d, e_21, _e, _f;
const groups = new Map();
const addGroup = (name) => {
if (!groups.has(name)) {
if (itemKeyFunction !== undefined) {
groups.set(name, {});
}
else {
groups.set(name, []);
}
}
};
try {
for (var _g = true, _h = __asyncValues(toAsyncIterable(data)), _j; _j = yield __await(_h.next()), _a = _j.done, !_a; _g = true) {
_c = _j.value;
_g = false;
const item = _c;
const group = yield __await(groupKeyFunction(item));
const itemKey = itemKeyFunction !== undefined ? yield __await(itemKeyFunction(item)) : undefined;
const itemGroups = (isAsyncIterable(group) || isIterable(group) || isIterator(group)) &&
!isString(group)
? group
: [group];
try {
for (var _k = true, _l = (e_21 = void 0, __asyncValues(distinctAsync(itemGroups))), _m; _m = yield __await(_l.next()), _d = _m.done, !_d; _k = true) {
_f = _m.value;
_k = false;
const itemGroup = _f;
addGroup(itemGroup);
if (itemKey === undefined) {
groups.get(itemGroup).push(item);
}
else {
groups.get(itemGroup)[itemKey] = item;
}
}
}
catch (e_21_1) { e_21 = { error: e_21_1 }; }
finally {
try {
if (!_k && !_d && (_e = _l.return)) yield __await(_e.call(_l));
}
finally { if (e_21) throw e_21.error; }
}
}
}
catch (e_20_1) { e_20 = { error: e_20_1 }; }
finally {
try {
if (!_g && !_a && (_b = _h.return)) yield __await(_b.call(_h));
}
finally { if (e_20) throw e_20.error; }
}
for (const group of groups) {
yield yield __await(group);
}
});
}
/**
* Sorts the given collection.
*
* If comparator is null, the elements of given iterable must be comparable.
*
* @param data
* @param comparator
*/
export function* sort(data, comparator) {
const result = toArray(data);
if (comparator !== undefined) {
result.sort(comparator);
}
else {
result.sort();
}
for (const datum of result) {
yield datum;
}
}
/**
* Sorts the given collection.
*
* If comparator is null, the elements of given iterable must be comparable.
*
* @param data
* @param comparator
*/
export function sortAsync(data, comparator) {
return __asyncGenerator(this, arguments, function* sortAsync_1() {
const result = yield __await(toArrayAsync(data));
if (comparator !== undefined) {
result.sort(comparator);
}
else {
result.sort();
}
for (const datum of result) {
yield yield __await(datum);
}
});
}
//# sourceMappingURL=single.js.map