fluent-iterable
Version:
Provides LINQ-like fluent api operations for iterables and async iterables (ES2018+).
442 lines • 12 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const utils_1 = require("./utils");
function toArray(iterable) {
const array = [];
for (const t of iterable) {
array.push(t);
}
return array;
}
exports.toArray = toArray;
function* withIndex(iterable) {
let idx = 0;
for (const t of iterable) {
yield { idx: idx++, value: t };
}
}
exports.withIndex = withIndex;
function* takeWhile(iterable, condition) {
for (const t of iterable) {
if (!condition(t)) {
break;
}
yield t;
}
}
exports.takeWhile = takeWhile;
async function* takeWhileAsync(iterable, condition) {
for (const t of iterable) {
if (!(await condition(t))) {
break;
}
yield t;
}
}
exports.takeWhileAsync = takeWhileAsync;
function take(iterable, n) {
let counter = 0;
return takeWhile(iterable, () => counter++ < n);
}
exports.take = take;
function* skipWhile(iterable, condition) {
let found = false;
for (const t of iterable) {
found = found || !condition(t);
if (!found) {
continue;
}
yield t;
}
}
exports.skipWhile = skipWhile;
async function* skipWhileAsync(iterable, condition) {
let found = false;
for (const t of iterable) {
found = found || !(await condition(t));
if (!found) {
continue;
}
yield t;
}
}
exports.skipWhileAsync = skipWhileAsync;
function skip(iterable, n) {
let counter = n;
return skipWhile(iterable, () => counter-- > 0);
}
exports.skip = skip;
function* map(iterable, mapper) {
for (const t of iterable) {
yield mapper(t);
}
}
exports.map = map;
async function* mapAsync(iterable, mapper) {
for (const t of iterable) {
yield await mapper(t);
}
}
exports.mapAsync = mapAsync;
function* filter(iterable, predicate) {
for (const t of iterable) {
if (predicate(t)) {
yield t;
}
}
}
exports.filter = filter;
async function* filterAsync(iterable, predicate) {
for (const t of iterable) {
if (await predicate(t)) {
yield t;
}
}
}
exports.filterAsync = filterAsync;
function* readPartition(iterator, next, size) {
for (; size > 0; --size) {
if (next.done) {
break;
}
yield next.value;
if (size > 1) {
next = iterator.next();
}
}
}
function* partition(iterable, size) {
if (size < 1) {
throw new Error(`Validation failed, size (${size}) expected to be bigger than 0`);
}
const iterator = iterable[Symbol.iterator]();
for (let next = iterator.next(); !next.done; next = iterator.next()) {
yield readPartition(iterator, next, size);
}
}
exports.partition = partition;
function* append(iterable, item) {
yield* iterable;
yield item;
}
exports.append = append;
function* prepend(iterable, item) {
yield item;
yield* iterable;
}
exports.prepend = prepend;
function* concat(...iterables) {
for (const iterable of iterables) {
yield* iterable;
}
}
exports.concat = concat;
function* repeat(iterable, n) {
if (n < 1) {
return;
}
const cache = [];
for (const t of iterable) {
yield t;
cache.push(t);
}
for (let i = 1; i < n; ++i) {
yield* cache;
}
}
exports.repeat = repeat;
function* flatten(iterable, mapper = t => t) {
for (const t of iterable) {
yield* mapper(t);
}
}
exports.flatten = flatten;
async function* flattenAsync(iterable, mapper) {
for (const t of iterable) {
yield* await mapper(t);
}
}
exports.flattenAsync = flattenAsync;
function* sort(iterable, comparer) {
yield* toArray(iterable).sort(comparer);
}
exports.sort = sort;
function* distinct(iterable, mapper = utils_1.identity) {
const set = new Set();
for (const t of iterable) {
const value = mapper(t);
if (set.has(value)) {
continue;
}
set.add(value);
yield t;
}
}
exports.distinct = distinct;
async function* distinctAsync(iterable, mapper) {
const set = new Set();
for (const t of iterable) {
const value = await mapper(t);
if (set.has(value)) {
continue;
}
set.add(value);
yield t;
}
}
exports.distinctAsync = distinctAsync;
function* group(iterable, mapper) {
const groups = new Map();
for (const t of iterable) {
const key = mapper(t);
const values = groups.get(key) || [];
values.push(t);
groups.set(key, values);
}
for (const [key, values] of groups.entries()) {
yield { key, values };
}
}
exports.group = group;
async function* groupAsync(iterable, mapper) {
const groups = new Map();
for (const t of iterable) {
const key = await mapper(t);
const values = groups.get(key) || [];
values.push(t);
groups.set(key, values);
}
for (const [key, values] of groups.entries()) {
yield { key, values };
}
}
exports.groupAsync = groupAsync;
function count(iterable, predicate = utils_1.truth) {
let counter = 0;
for (const t of iterable) {
if (predicate(t)) {
counter++;
}
}
return counter;
}
exports.count = count;
async function countAsync(iterable, predicate) {
let counter = 0;
for (const t of iterable) {
if (await predicate(t)) {
counter++;
}
}
return counter;
}
exports.countAsync = countAsync;
function first(iterable, predicate = utils_1.truth) {
for (const t of iterable) {
if (predicate(t)) {
return t;
}
}
return undefined;
}
exports.first = first;
async function firstAsync(iterable, predicate) {
for (const t of iterable) {
if (await predicate(t)) {
return t;
}
}
return undefined;
}
exports.firstAsync = firstAsync;
function last(iterable, predicate = utils_1.truth) {
let result;
for (const t of iterable) {
if (predicate(t)) {
result = t;
}
}
return result;
}
exports.last = last;
async function lastAsync(iterable, predicate) {
let result;
for (const t of iterable) {
if (await predicate(t)) {
result = t;
}
}
return result;
}
exports.lastAsync = lastAsync;
function reduceAndMap(iterable, reducer, initial, result) {
let accumulator = initial;
for (const t of iterable) {
accumulator = reducer(accumulator, t);
}
return result(accumulator);
}
exports.reduceAndMap = reduceAndMap;
async function reduceAndMapAsync(iterable, reducer, initial, result) {
let accumulator = initial;
for (const t of iterable) {
accumulator = await reducer(accumulator, t);
}
return result(accumulator);
}
exports.reduceAndMapAsync = reduceAndMapAsync;
function reduce(iterable, reducer, initial) {
return reduceAndMap(iterable, reducer, initial, utils_1.identity);
}
exports.reduce = reduce;
function reduceAsync(iterable, reducer, initial) {
return reduceAndMapAsync(iterable, reducer, initial, utils_1.identityAsync);
}
exports.reduceAsync = reduceAsync;
function all(iterable, predicate) {
for (const t of iterable) {
if (!predicate(t)) {
return false;
}
}
return true;
}
exports.all = all;
async function allAsync(iterable, predicate) {
for (const t of iterable) {
if (!(await predicate(t))) {
return false;
}
}
return true;
}
exports.allAsync = allAsync;
function any(iterable, predicate = utils_1.truth) {
return first(iterable, predicate) !== undefined;
}
exports.any = any;
async function anyAsync(iterable, predicate) {
return (await firstAsync(iterable, predicate)) !== undefined;
}
exports.anyAsync = anyAsync;
function contains(iterable, item) {
return any(iterable, next => next === item);
}
exports.contains = contains;
function toObject(iterable, keySelector, valueSelector = utils_1.identity) {
const res = {};
for (const t of iterable) {
res[keySelector(t)] = valueSelector(t);
}
return res;
}
exports.toObject = toObject;
async function toObjectAsync(iterable, keySelector, valueSelector) {
const res = {};
for (const t of iterable) {
res[await keySelector(t)] = await valueSelector(t);
}
return res;
}
exports.toObjectAsync = toObjectAsync;
async function* toAsync(iterable) {
yield* iterable;
}
exports.toAsync = toAsync;
function forEach(iterable, action) {
for (const t of iterable) {
action(t);
}
}
exports.forEach = forEach;
async function forEachAsync(iterable, action) {
for (const t of iterable) {
await action(t);
}
}
exports.forEachAsync = forEachAsync;
function* execute(iterable, action) {
for (const t of iterable) {
action(t);
yield t;
}
}
exports.execute = execute;
async function* executeAsync(iterable, action) {
for (const t of iterable) {
await action(t);
yield t;
}
}
exports.executeAsync = executeAsync;
function join(iterable, separator, mapper = utils_1.identity) {
return (reduce(iterable, (current, next) => {
const nextStr = mapper(next);
return current ? `${current}${separator}${nextStr}` : nextStr;
}, undefined) || '');
}
exports.join = join;
async function joinAsync(iterable, separator, mapper) {
return ((await reduceAsync(iterable, async (current, next) => {
const nextStr = await mapper(next);
return current ? `${current}${separator}${nextStr}` : nextStr;
}, undefined)) || '');
}
exports.joinAsync = joinAsync;
function sum(iterable, mapper = utils_1.identity) {
return reduce(iterable, (current, next) => current + mapper(next), 0);
}
exports.sum = sum;
function sumAsync(iterable, mapper) {
return reduceAsync(iterable, async (current, next) => current + (await mapper(next)), 0);
}
exports.sumAsync = sumAsync;
function avg(iterable, mapper = utils_1.identity) {
return reduceAndMap(iterable, (current, next) => ({
avg: (current.avg * current.count + mapper(next)) / (current.count + 1),
count: current.count + 1,
}), { avg: 0, count: 0 }, acc => acc.avg);
}
exports.avg = avg;
function avgAsync(iterable, mapper) {
return reduceAndMapAsync(iterable, async (current, next) => ({
avg: (current.avg * current.count + (await mapper(next))) / (current.count + 1),
count: current.count + 1,
}), { avg: 0, count: 0 }, async (acc) => acc.avg);
}
exports.avgAsync = avgAsync;
function top(iterable, mapper, comparer) {
return reduceAndMap(iterable, (current, next) => {
const value = mapper(next);
return !current.found || (current.value && comparer(value, current.value) > 0)
? { value, item: next, found: true }
: current;
}, { value: undefined, item: undefined, found: false }, acc => acc.item);
}
exports.top = top;
function topAsync(iterable, mapper, comparer) {
return reduceAndMapAsync(iterable, async (current, next) => {
const value = await mapper(next);
return !current.found || (current.value && comparer(value, current.value) > 0)
? { value, item: next, found: true }
: current;
}, { value: undefined, item: undefined, found: false }, async (acc) => acc.item);
}
exports.topAsync = topAsync;
function min(iterable, mapper = utils_1.identity) {
return top(iterable, mapper, (a, b) => b - a);
}
exports.min = min;
function minAsync(iterable, mapper) {
return topAsync(iterable, mapper, (a, b) => b - a);
}
exports.minAsync = minAsync;
function max(iterable, mapper = utils_1.identity) {
return top(iterable, mapper, (a, b) => a - b);
}
exports.max = max;
function maxAsync(iterable, mapper) {
return topAsync(iterable, mapper, (a, b) => a - b);
}
exports.maxAsync = maxAsync;
//# sourceMappingURL=fluentFunctions.js.map