fast-iterable
Version:
Provides LINQ-like fluent api operations for iterables and async iterables (ES2018+).
276 lines (275 loc) • 7.89 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.iterateObjEntries = exports.iterateObjProps = exports.iterateAll = exports.iterate = exports.iterateAllAsync = exports.iterateAsync = exports.lt = exports.le = exports.gt = exports.ge = exports.eq = exports.getAverageStepper = exports.fluentGroup = exports.asyncNegation = exports.negation = exports.falsity = exports.truth = exports.identity = exports.emptyAsync = exports.empty = exports.constant = exports.assureOrderDescending = exports.assureOrder = exports.isPromise = exports.desc = exports.asc = void 0;
/* eslint-disable guard-for-in */
/* eslint-disable @typescript-eslint/no-empty-function */
const fluent_1 = require("../fluent");
const types_internal_1 = require("../types-internal");
const string_wrapper_1 = require("../types-internal/string-wrapper");
const map_1 = require("../sync/map");
const valueTypes = ['string', 'number', 'boolean'];
/**
* Returns exactly the informed parameter
* @param param The informed parameter to be returned
*/
function identity(param) {
return param;
}
exports.identity = identity;
/**
* @internal
*/
async function* promiseIterateAsync(a) {
yield* await a;
}
/**
* Iterates all element of an async iterable
* @typeparam T the item type of the [[Iterable]]
* @param a The async iterable
*/
function iterateAsync(a) {
return (a.then || a[Symbol.iterator]
? promiseIterateAsync(a)
: a);
}
exports.iterateAsync = iterateAsync;
/**
* Iterates in all elements of an async iterable of iterables or async iterables
* @typeparam T the item type of the internal [[Iterable/AsyncIterable]]
* @param a The async iterable
*/
async function* iterateAllAsync(a) {
for await (const it of a) {
yield* it;
}
}
exports.iterateAllAsync = iterateAllAsync;
/**
* Iterates all element of an iterable
* @typeparam T the item type of the [[Iterable]]
* @param a The iterable
*/
const iterate = identity;
exports.iterate = iterate;
/**
* Returns a function that always returns the informed value
* @param value the constant value
*/
function constant(value) {
return function constantValue() {
return value;
};
}
exports.constant = constant;
/**
* Iterates in all elements of an iterable of iterables
* @typeparam T the item type of the internal [[Iterable]]
* @param a The iterable
*/
function* iterateAll(a) {
for (const it of a) {
yield* it;
}
}
exports.iterateAll = iterateAll;
/**
* Iterates over all owned properties of the given object
* @param obj The object to iterate with
*/
function* iterateObjProps(obj) {
for (const property in obj) {
yield property;
}
}
exports.iterateObjProps = iterateObjProps;
/**
* Iterates over all owned entries of given object
* @param obj The object to iterate with
*/
function iterateObjEntries(obj) {
return map_1.map.call(iterateObjProps(obj), (property) => [
property,
obj[property],
]);
}
exports.iterateObjEntries = iterateObjEntries;
/**
* Provides a "equals" comparer
* @typeparam T the type of b
* @param b the value for comparison
*/
function eq(b) {
return (a) => a === b;
}
exports.eq = eq;
/**
* Provides a "greater than" comparer
* @typeparam T the type of b
* @param b the value for comparison
*/
function gt(b) {
return (a) => a > b;
}
exports.gt = gt;
/**
* Provides a "greater or equal" comparer
* @typeparam T the type of b
* @param b the value for comparison
*/
function ge(b) {
return (a) => a >= b;
}
exports.ge = ge;
/**
* Provides a "lesser than" comparer
* @typeparam T the type of b
* @param b the value for comparison
*/
function lt(b) {
return (a) => a < b;
}
exports.lt = lt;
/**
* Provides a "lesser or equal" comparer
* @typeparam T the type of b
* @param b the value for comparison
*/
function le(b) {
return (a) => a <= b;
}
exports.le = le;
/**
* Provides an empty iterable
*/
function* empty() { }
exports.empty = empty;
/**
* Provides an empty async iterable
*/
async function* emptyAsync() { }
exports.emptyAsync = emptyAsync;
/**
* Always returns true
*/
function truth() {
return true;
}
exports.truth = truth;
/**
* Always returns false
*/
function falsity() {
return false;
}
exports.falsity = falsity;
/**
* Provides a function that negates the informed predicate
* @typeparam T the item type of the [[Predicate]]
* @param predicate The predicate to be negated
*/
function negation(predicate) {
return (item) => !predicate(item);
}
exports.negation = negation;
/**
* Provides a function that negates the informed async predicate
* @typeparam T the item type of the [[AsyncPredicate]]
* @param predicate The async predicate to be negated
*/
function asyncNegation(predicate) {
return async (item) => !(await predicate(item));
}
exports.asyncNegation = asyncNegation;
/**
* Convert a simple [[Group]] to a [[FluentGroup]]
* @typeparam Key The type of the key
* @typeparam Value the type of the items of the value property
* @param {Group} grp the [[Group]] to be converted
*/
function fluentGroup(grp) {
return {
...grp,
values: (0, fluent_1.default)(grp.values),
};
}
exports.fluentGroup = fluentGroup;
/**
* Returns an object to calculates incremental average/iterative means
*/
function getAverageStepper() {
let avg = 0;
let count = 0;
const wrapper = {
get avg() {
return count ? avg : NaN;
},
step: (y) => (avg = avg + (y - avg) / ++count),
};
return wrapper;
}
exports.getAverageStepper = getAverageStepper;
function getItemToAssure(f) {
return typeof f === 'function'
? (...args) => f(...args)
: f;
}
/**
* Returns a new instance of a function with a order assuring mark.
* Fluent Iterable will treat order Assuring marked function as if
* they're guaranteed to return ordered result in regard some iterable
* where they're applied. The actual order, though, is of responsibility
* of the code using this package.
*
* This is useful to have access to faster versions of some algorithms, but
* the output may not match expectation if the resulting order is not actually right.
*
* @param f the function to assure order
*/
function assureOrder(f) {
const result = getItemToAssure(f);
result[types_internal_1.orderAssured] = 1;
return result;
}
exports.assureOrder = assureOrder;
/**
* Returns a new instance of a function with a descending order assuring mark.
* Fluent Iterable will treat descending order assuring marked functions as if
* they're guaranteed to return descending ordered results in regard some iterable
* where they're applied. The actual order, though, is of responsibility
* of the code using this package.
*
* This is useful to have access to faster versions of some algorithms, but
* the output may not match expectation if the resulting order is not actually right.
*
* @param f the function to assure order
*/
function assureOrderDescending(f) {
const result = getItemToAssure(f);
result[types_internal_1.orderAssured] = -1;
return result;
}
exports.assureOrderDescending = assureOrderDescending;
function isValueType(f) {
const tp = typeof f;
return valueTypes.includes(tp);
}
/**
* Mark a field name or a mapper as ascending, for use with sortBy
* @param f the mapper or the field name
*/
function asc(f) {
return assureOrder((isValueType(f) ? { [string_wrapper_1.valueTypeWrapper]: f } : f));
}
exports.asc = asc;
/**
* Mark a field name or a mapper as descending, for use with sortBy
* @param f the mapper or the field name
*/
function desc(f) {
return assureOrderDescending((isValueType(f) ? { [string_wrapper_1.valueTypeWrapper]: f } : f));
}
exports.desc = desc;
function isPromise(t) {
return !!(t && typeof t.then === 'function');
}
exports.isPromise = isPromise;