UNPKG

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
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