@luvies/lazy
Version:
A linq-like lazy iteration module that aims to support deno, node & browser
407 lines • 9.65 kB
JavaScript
;
/*
Iterable aggregation functions.
All of these function cause the iterable to be iterated.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.toMap = exports.toArray = exports.sum = exports.stringJoin = exports.singleOrDefault = exports.single = exports.resolveAll = exports.min = exports.max = exports.lastOrDefault = exports.last = exports.iterableEquals = exports.forEach = exports.firstOrDefault = exports.first = exports.elementAtOrDefault = exports.elementAt = exports.count = exports.contains = exports.average = exports.any = exports.all = exports.aggregate = exports.Errors = void 0;
/**
* Error messages.
* @hidden
*/
var Errors;
(function (Errors) {
Errors["Empty"] = "Empty iterable";
Errors["NonNumber"] = "Cannot perform function on a non-number value";
})(Errors = exports.Errors || (exports.Errors = {}));
function aggregate(iterable, agg, seed) {
const gotSeed = arguments.length >= 3;
if (gotSeed) {
let acc = seed;
for (const element of iterable) {
acc = agg(acc, element);
}
return acc;
}
else {
let items = false;
let acc;
for (const element of iterable) {
if (!items) {
acc = element;
}
else {
acc = agg(acc, element);
}
items = true;
}
if (!items) {
throw new Error(Errors.Empty);
}
return acc;
}
}
exports.aggregate = aggregate;
/**
* @hidden
*/
function all(iterable, predicate) {
for (const element of iterable) {
if (!predicate(element)) {
return false;
}
}
return true;
}
exports.all = all;
/**
* @hidden
*/
function any(iterable, predicate) {
if (predicate) {
for (const element of iterable) {
if (predicate(element)) {
return true;
}
}
return false;
}
else {
return !iterable[Symbol.iterator]().next().done;
}
}
exports.any = any;
function average(iterable, selector) {
let total = 0;
let ccount = 0;
for (const element of iterable) {
const value = selector ? selector(element) : element;
if (typeof value !== 'number') {
throw new TypeError(Errors.NonNumber);
}
total += value;
ccount++;
}
if (ccount === 0) {
throw new Error(Errors.Empty);
}
return (total / ccount);
}
exports.average = average;
/**
* @hidden
*/
function contains(iterable, element, comparer) {
for (const ielement of iterable) {
if (comparer ? comparer(element, ielement) : element === ielement) {
return true;
}
}
return false;
}
exports.contains = contains;
/**
* @hidden
*/
function count(iterable, predicate) {
let ccount = 0;
for (const element of iterable) {
if (!predicate || predicate(element)) {
ccount++;
}
}
return ccount;
}
exports.count = count;
/**
* @hidden
*/
function getElementAt(iterable, index) {
let cindex = 0;
for (const element of iterable) {
if (cindex === index) {
return { found: true, element };
}
cindex++;
}
return { found: false };
}
/**
* @hidden
*/
function elementAt(iterable, index) {
if (index < 0) {
throw new Error('Index cannot be negative');
}
const res = getElementAt(iterable, index);
if (res.found) {
return res.element;
}
else {
throw new Error(`No element found at index ${index}`);
}
}
exports.elementAt = elementAt;
function elementAtOrDefault(iterable, index, defaultValue) {
const res = getElementAt(iterable, index);
if (res.found) {
return res.element;
}
else {
return defaultValue;
}
}
exports.elementAtOrDefault = elementAtOrDefault;
/**
* @hidden
*/
function getFirst(iterable, predicate) {
for (const element of iterable) {
if (!predicate || predicate(element)) {
return { items: true, element };
}
}
return { items: false };
}
/**
* @hidden
*/
function first(iterable, predicate) {
const res = getFirst(iterable, predicate);
if (res.items) {
return res.element;
}
else {
throw new Error(Errors.Empty);
}
}
exports.first = first;
function firstOrDefault(iterable, defaultValue, predicate) {
const res = getFirst(iterable, predicate);
if (res.items) {
return res.element;
}
else {
return defaultValue;
}
}
exports.firstOrDefault = firstOrDefault;
/**
* @hidden
*/
function forEach(iterable, callbackFn) {
let index = 0;
for (const element of iterable) {
callbackFn(element, index);
index++;
}
}
exports.forEach = forEach;
/**
* @hidden
*/
function iterableEquals(firstIterable, secondIterable, comparer) {
let done = false;
const firstIter = firstIterable[Symbol.iterator]();
let firstMove;
const secondIter = secondIterable[Symbol.iterator]();
let secondMove;
do {
firstMove = firstIter.next();
secondMove = secondIter.next();
if (firstMove.done !== secondMove.done) {
return false;
}
else if (firstMove.done && secondMove.done) {
done = true;
}
else if (comparer
? !comparer(firstMove.value, secondMove.value)
: firstMove.value !== secondMove.value) {
return false;
}
} while (!done);
return true;
}
exports.iterableEquals = iterableEquals;
/**
* @hidden
*/
function getLast(iterable, predicate) {
let items = false;
let latest;
for (const element of iterable) {
if (!predicate || predicate(element)) {
latest = element;
items = true;
}
}
if (items) {
return { items: true, element: latest };
}
else {
return { items: false };
}
}
/**
* @hidden
*/
function last(iterable, predicate) {
const res = getLast(iterable, predicate);
if (res.items) {
return res.element;
}
else {
throw new Error(Errors.Empty);
}
}
exports.last = last;
function lastOrDefault(iterable, defaultValue, predicate) {
const res = getLast(iterable, predicate);
if (res.items) {
return res.element;
}
else {
return defaultValue;
}
}
exports.lastOrDefault = lastOrDefault;
function max(iterable, selector) {
let cmax = -Infinity;
let items = false;
for (const element of iterable) {
const value = selector ? selector(element) : element;
if (typeof value !== 'number') {
throw new TypeError(Errors.NonNumber);
}
if (value > cmax) {
cmax = value;
}
items = true;
}
if (!items) {
throw new Error(Errors.Empty);
}
return cmax;
}
exports.max = max;
function min(iterable, selector) {
let cmin = +Infinity;
let items = false;
for (const element of iterable) {
const value = selector ? selector(element) : element;
if (typeof value !== 'number') {
throw new TypeError(Errors.NonNumber);
}
if (value < cmin) {
cmin = value;
}
items = true;
}
if (!items) {
throw new Error(Errors.Empty);
}
return cmin;
}
exports.min = min;
/**
* @hidden
*/
function resolveAll(iterable) {
return Promise.all(iterable);
}
exports.resolveAll = resolveAll;
/**
* @hidden
*/
function getSingle(iterable, predicate) {
for (const element of iterable) {
if (predicate(element)) {
return { found: true, element };
}
}
return { found: false };
}
/**
* @hidden
*/
function single(iterable, predicate) {
const res = getSingle(iterable, predicate);
if (res.found) {
return res.element;
}
else {
throw new Error(Errors.Empty);
}
}
exports.single = single;
function singleOrDefault(iterable, predicate, defaultValue) {
const res = getSingle(iterable, predicate);
if (res.found) {
return res.element;
}
else {
return defaultValue;
}
}
exports.singleOrDefault = singleOrDefault;
/**
* @hidden
*/
function stringJoin(iterable, separator = '', strFn = String) {
let str = '';
let started = false;
for (const element of iterable) {
if (started) {
str += separator;
}
str += strFn(element);
started = true;
}
return str;
}
exports.stringJoin = stringJoin;
function sum(iterable, selector) {
let total = 0;
let items = false;
for (const element of iterable) {
const value = selector ? selector(element) : element;
if (typeof value !== 'number') {
throw new TypeError(Errors.NonNumber);
}
total += value;
items = true;
}
if (!items) {
throw new Error(Errors.Empty);
}
return total;
}
exports.sum = sum;
/**
* @hidden
*/
function toArray(iterable) {
const arr = [];
for (const element of iterable) {
arr.push(element);
}
return arr;
}
exports.toArray = toArray;
/**
* @hidden
*/
function toMap(iterable, keyFn, valueFn) {
const map = new Map();
for (const element of iterable) {
const key = keyFn(element);
if (map.has(key)) {
throw new Error('Duplicate key found');
}
map.set(key, valueFn ? valueFn(element) : element);
}
return map;
}
exports.toMap = toMap;
//# sourceMappingURL=aggregates.js.map