@opencreek/ext
Advanced tools
Comparing version 2.0.0--canary.21.3702576932.0 to 2.0.0--canary.22.3712435423.0
@@ -1,5 +0,107 @@ | ||
export * from "@opencreek/deno-std-collections"; | ||
export declare function filterNotNullish<T>(arr: Array<T>): Array<NonNullable<T>>; | ||
export declare function mapAsync<T, U>(arr: Array<T>, f: (e: T, index: number, array: Array<T>) => Promise<U>): Promise<Array<U>>; | ||
export declare function filterAsync<T>(arr: Array<T>, f: (e: T, index: number, array: Array<T>) => Promise<boolean>): Promise<Array<T>>; | ||
declare type PairSplit<T> = T extends [infer F, infer L] ? [Chain<F>, Chain<L>] : never; | ||
declare type IfString<T, U> = T extends string ? U : never; | ||
declare type FlattenChain<T> = T extends Chain<infer U> ? Chain<U> : never; | ||
export declare function objChain<K extends string | number | symbol, T>(value: Record<K, T> | ObjectChain<K, T> | Chain<readonly [K, T]>): ObjectChain<K, T>; | ||
export declare function chain<T>(value: ReadonlyArray<T> | Chain<T> | Iterable<T>): Chain<T>; | ||
export declare class ObjectChain<K extends string | number | symbol, T> { | ||
private val; | ||
constructor(val: Record<K, T>); | ||
value(): Record<K, T>; | ||
keys(): Chain<K>; | ||
values(): Chain<T>; | ||
mapKeys<U extends string | number | symbol>(transformer: (key: K) => U): ObjectChain<U, T>; | ||
mapValues<V>(transformer: (value: T) => V): ObjectChain<K, V>; | ||
mapEntries<U extends string | number | symbol, V>(transformer: (key: K, value: T) => [U, V]): ObjectChain<U, V>; | ||
filterKeys(filter: (key: K) => boolean): ObjectChain<K, T>; | ||
filterValues(filter: (value: T) => boolean): ObjectChain<K, T>; | ||
filterEntries(filter: (key: K, value: T) => boolean): ObjectChain<K, T>; | ||
} | ||
export declare class Chain<T> { | ||
private val; | ||
constructor(val: ReadonlyArray<T>); | ||
value(): ReadonlyArray<T>; | ||
associateBy<S extends string | number | symbol>(selector: (el: T) => S): ObjectChain<S, T>; | ||
associateWith<U>(selector: (key: string) => U): IfString<T, ObjectChain<string, U>>; | ||
chunk(size: number): Chain<T[]>; | ||
distinct(): Chain<T>; | ||
distinctBy<D>(selector: (el: T) => D): Chain<T>; | ||
dropLastWhile(predicate: (el: T) => boolean): Chain<T>; | ||
dropWhile(predicate: (el: T) => boolean): Chain<T>; | ||
every<S extends T>(predicate: (el: T, index: number, array: ReadonlyArray<T>) => el is S): this is Chain<S>; | ||
every(predicate: (el: T, index: number, array: ReadonlyArray<T>) => boolean): boolean; | ||
some(predicate: (value: T, index: number, array: ReadonlyArray<T>) => boolean): boolean; | ||
first(): T; | ||
firstOrNull(): T | undefined; | ||
filter(filter: (el: T, index: number, array: ReadonlyArray<T>) => boolean): Chain<T>; | ||
filterAsync(predicate: (el: T, index: number, array: ReadonlyArray<T>) => Promise<boolean>): Promise<Chain<T>>; | ||
filterNotNullish(): Chain<NonNullable<T>>; | ||
find<S extends T>(predicate: (el: T, index: number, array: ReadonlyArray<T>) => el is S): S | undefined; | ||
findIndex(predicate: (el: T, index: number, array: ReadonlyArray<T>) => boolean): number | undefined; | ||
findLast(predicate: (el: T) => boolean): T | undefined; | ||
findLastIndex(predicate: (el: T) => boolean): number | undefined; | ||
findSingle(predicate: (el: T) => boolean): T | undefined; | ||
firstNotNullishOf<O>(selector: (item: T) => O | undefined | null): NonNullable<O> | undefined; | ||
flatten(): FlattenChain<T>; | ||
flatMap<U>(transformer: (el: T, index: number, array: ReadonlyArray<T>) => Chain<U>): Chain<U>; | ||
forEach(callback: (el: T, index: number, array: ReadonlyArray<T>) => void): void; | ||
groupBy<K extends string | symbol | number>(selector: (el: T) => K): ObjectChain<K, ReadonlyArray<T>>; | ||
indexOf(searchElement: T, fromIndex?: number): number | undefined; | ||
lastIndexOf(searchElement: T, fromIndex?: number): number | undefined; | ||
includes(el: T, fromIndex?: number): boolean; | ||
intersect(...arrays: (readonly T[])[]): Chain<T>; | ||
join(separator?: string): string; | ||
mapJoin(separator: string, transformer: (el: T) => string): string; | ||
last(): T; | ||
lastOrNull(): T | undefined; | ||
map<U>(transformer: (el: T, index: number, array: ReadonlyArray<T>) => U): Chain<U>; | ||
mapAsync<U>(transformer: (el: T, index: number, array: ReadonlyArray<T>) => Promise<U>): Promise<Chain<U>>; | ||
mapNotNullish<O>(transformer: (el: T) => O): Chain<NonNullable<O>>; | ||
maxBy(selector: (el: T) => string): T | undefined; | ||
maxBy(selector: (el: T) => bigint): T | undefined; | ||
maxBy(selector: (el: T) => number): T | undefined; | ||
maxBy(selector: (el: T) => Date): T | undefined; | ||
maxOf(selector: (el: T) => bigint): bigint | undefined; | ||
maxOf(selector: (el: T) => number): number | undefined; | ||
maxOf(selector: (el: T) => string): string | undefined; | ||
maxOf(selector: (el: T) => Date): Date | undefined; | ||
maxWith(comparator: (a: T, b: T) => number): T | undefined; | ||
minBy(selector: (el: T) => number): T | undefined; | ||
minBy(selector: (el: T) => string): T | undefined; | ||
minBy(selector: (el: T) => bigint): T | undefined; | ||
minBy(selector: (el: T) => Date): T | undefined; | ||
minOf(selector: (el: T) => bigint): bigint | undefined; | ||
minOf(selector: (el: T) => number): number | undefined; | ||
minOf(selector: (el: T) => string): string | undefined; | ||
minOf(selector: (el: T) => Date): Date | undefined; | ||
minWith(comparator: (a: T, b: T) => number): T | undefined; | ||
partition(predicate: (el: T) => boolean): [Chain<T>, Chain<T>]; | ||
permutations(): Chain<T[]>; | ||
reduce(reducer: (accumulator: T, current: T, index: number, array: ReadonlyArray<T>) => T): T; | ||
reduce(reducer: (accumulator: T, current: T, index: number, array: ReadonlyArray<T>) => T, initial: T): T; | ||
reduce<O>(reducer: (accumulator: O, current: T, index: number, array: ReadonlyArray<T>) => O, initial: O): O; | ||
reduceRight(reducer: (accumulator: T, current: T, index: number, array: ReadonlyArray<T>) => T): T; | ||
reduceRight(reducer: (accumulator: T, current: T, index: number, array: ReadonlyArray<T>) => T, initial: T): T; | ||
reduceRight<O>(reducer: (accumulator: O, current: T, index: number, array: ReadonlyArray<T>) => O, initial: O): O; | ||
reverse(): Chain<T>; | ||
runningReduce<O>(reducer: (accumulator: O, current: T) => O, initialValue: O): Chain<O>; | ||
sample(): T | undefined; | ||
slice(start?: number, end?: number): Chain<T>; | ||
slidingWindows(size: number, { step, partial }: { | ||
step: number; | ||
partial: boolean; | ||
}): Chain<T[]>; | ||
sort(compareFn?: (a: T, b: T) => number): Chain<T>; | ||
sortBy(selector: (el: T) => Date): Chain<T>; | ||
sortBy(selector: (el: T) => bigint): Chain<T>; | ||
sortBy(selector: (el: T) => string): Chain<T>; | ||
sortBy(selector: (el: T) => number): Chain<T>; | ||
sumOf(selector: (el: T) => number): number; | ||
takeLastWhile(predicate: (el: T) => boolean): Chain<T>; | ||
takeWhile(predicate: (el: T) => boolean): Chain<T>; | ||
union(...arrays: (readonly T[])[]): Chain<T>; | ||
unzip(): PairSplit<T>; | ||
withoutAll(values: readonly T[]): Chain<T>; | ||
zip<U>(withArray: readonly U[]): Chain<[T, U]>; | ||
} | ||
export {}; | ||
//# sourceMappingURL=collections.d.ts.map |
"use strict"; | ||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); | ||
}) : (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
o[k2] = m[k]; | ||
})); | ||
var __exportStar = (this && this.__exportStar) || function(m, exports) { | ||
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); | ||
}; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
@@ -22,21 +12,342 @@ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.filterAsync = exports.mapAsync = exports.filterNotNullish = void 0; | ||
__exportStar(require("@opencreek/deno-std-collections"), exports); | ||
function filterNotNullish(arr) { | ||
return arr.filter((it) => it != null); | ||
exports.Chain = exports.ObjectChain = exports.chain = exports.objChain = void 0; | ||
const deno_std_collections_1 = require("@opencreek/deno-std-collections"); | ||
const _1 = require("."); | ||
function objChain(value) { | ||
if (value instanceof ObjectChain) { | ||
return value; | ||
} | ||
if (value instanceof Chain) { | ||
return new ObjectChain(Object.fromEntries(value.value())); | ||
} | ||
return new ObjectChain(value); | ||
} | ||
exports.filterNotNullish = filterNotNullish; | ||
function mapAsync(arr, f) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
return Promise.all(arr.map(f)); | ||
}); | ||
exports.objChain = objChain; | ||
function chain(value) { | ||
if (value instanceof Chain) | ||
return value; | ||
if (Array.isArray(value)) | ||
return new Chain(value); | ||
return new Chain([...value]); | ||
} | ||
exports.mapAsync = mapAsync; | ||
function filterAsync(arr, f) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const includes = yield mapAsync(arr, f); | ||
return arr.filter((_, index) => includes[index]); | ||
}); | ||
exports.chain = chain; | ||
class ObjectChain { | ||
constructor(val) { | ||
this.val = val; | ||
} | ||
value() { | ||
return this.val; | ||
} | ||
keys() { | ||
return new Chain(Object.keys(this.val)); | ||
} | ||
values() { | ||
return new Chain(Object.values(this.val)); | ||
} | ||
mapKeys(transformer) { | ||
const entries = Object.entries(this.val); | ||
const mapped = entries.map(([k, v]) => { | ||
return [transformer(k), v]; | ||
}); | ||
return new ObjectChain(Object.fromEntries(mapped)); | ||
} | ||
mapValues(transformer) { | ||
const entries = Object.entries(this.val); | ||
const mapped = entries.map(([k, v]) => { | ||
return [k, transformer(v)]; | ||
}); | ||
return new ObjectChain(Object.fromEntries(mapped)); | ||
} | ||
mapEntries(transformer) { | ||
const entries = Object.entries(this.val); | ||
const mapped = entries.map(([k, v]) => { | ||
return transformer(k, v); | ||
}); | ||
return new ObjectChain(Object.fromEntries(mapped)); | ||
} | ||
filterKeys(filter) { | ||
const entries = Object.entries(this.val); | ||
const filtered = entries.filter(([k, _]) => { | ||
return filter(k); | ||
}); | ||
return new ObjectChain(Object.fromEntries(filtered)); | ||
} | ||
filterValues(filter) { | ||
const entries = Object.entries(this.val); | ||
const filtered = entries.filter(([_, v]) => { | ||
return filter(v); | ||
}); | ||
return new ObjectChain(Object.fromEntries(filtered)); | ||
} | ||
filterEntries(filter) { | ||
const entries = Object.entries(this.val); | ||
const filtered = entries.filter(([k, v]) => { | ||
return filter(k, v); | ||
}); | ||
return new ObjectChain(Object.fromEntries(filtered)); | ||
} | ||
} | ||
exports.filterAsync = filterAsync; | ||
exports.ObjectChain = ObjectChain; | ||
class Chain { | ||
constructor(val) { | ||
this.val = val; | ||
} | ||
value() { | ||
return this.val; | ||
} | ||
associateBy(selector) { | ||
const entries = this.map((m) => { | ||
return [selector(m), m]; | ||
}); | ||
return objChain(entries); | ||
} | ||
associateWith(selector) { | ||
const entries = this.map((el) => { | ||
return [ | ||
el, | ||
selector(el), | ||
]; | ||
}); | ||
return objChain(entries); | ||
} | ||
chunk(size) { | ||
const chunks = (0, deno_std_collections_1.chunk)(this.val, size); | ||
return new Chain(chunks); | ||
} | ||
distinct() { | ||
const unique = (0, deno_std_collections_1.distinct)(this.val); | ||
return new Chain(unique); | ||
} | ||
distinctBy(selector) { | ||
const unique = (0, deno_std_collections_1.distinctBy)(this.val, selector); | ||
return new Chain(unique); | ||
} | ||
dropLastWhile(predicate) { | ||
const dropped = (0, deno_std_collections_1.dropLastWhile)(this.val, predicate); | ||
return new Chain(dropped); | ||
} | ||
dropWhile(predicate) { | ||
const dropped = (0, deno_std_collections_1.dropWhile)(this.val, predicate); | ||
return new Chain(dropped); | ||
} | ||
every(predicate) { | ||
return this.val.every(predicate); | ||
} | ||
some(predicate) { | ||
return this.val.some(predicate); | ||
} | ||
first() { | ||
var _a; | ||
return (_a = this.firstOrNull()) !== null && _a !== void 0 ? _a : (0, _1.error)("No first element found"); | ||
} | ||
firstOrNull() { | ||
return this.val[0]; | ||
} | ||
filter(filter) { | ||
const filtered = this.val.filter(filter); | ||
return new Chain(filtered); | ||
} | ||
filterAsync(predicate) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const includes = yield this.mapAsync(predicate); | ||
return this.filter((_, index) => includes.val[index]); | ||
}); | ||
} | ||
filterNotNullish() { | ||
return this.filter((it) => it != null); | ||
} | ||
find(predicate) { | ||
return this.val.find(predicate); | ||
} | ||
findIndex(predicate) { | ||
const ret = this.val.findIndex(predicate); | ||
if (ret === -1) | ||
return undefined; | ||
return ret; | ||
} | ||
findLast(predicate) { | ||
return (0, deno_std_collections_1.findLast)(this.val, predicate); | ||
} | ||
findLastIndex(predicate) { | ||
return (0, deno_std_collections_1.findLastIndex)(this.val, predicate); | ||
} | ||
findSingle(predicate) { | ||
return (0, deno_std_collections_1.findSingle)(this.val, predicate); | ||
} | ||
firstNotNullishOf(selector) { | ||
return (0, deno_std_collections_1.firstNotNullishOf)(this.val, selector); | ||
} | ||
flatten() { | ||
const flattened = this.val.flatMap((it) => it instanceof Chain ? it.val : []); | ||
return new Chain(flattened); | ||
} | ||
flatMap(transformer) { | ||
return this.map(transformer).flatten(); | ||
} | ||
forEach(callback) { | ||
this.map(callback); | ||
} | ||
groupBy(selector) { | ||
var _a; | ||
const record = {}; | ||
for (const el of this.val) { | ||
const key = selector(el); | ||
if (record[key] != null) { | ||
(_a = record[key]) === null || _a === void 0 ? void 0 : _a.push(el); | ||
} | ||
else { | ||
record[key] = [el]; | ||
} | ||
} | ||
return new ObjectChain(record); | ||
} | ||
indexOf(searchElement, fromIndex) { | ||
const ret = this.val.indexOf(searchElement, fromIndex); | ||
if (ret === -1) | ||
return undefined; | ||
return ret; | ||
} | ||
lastIndexOf(searchElement, fromIndex) { | ||
const ret = this.val.lastIndexOf(searchElement, fromIndex); | ||
if (ret === -1) | ||
return undefined; | ||
return ret; | ||
} | ||
includes(el, fromIndex) { | ||
return this.val.includes(el, fromIndex); | ||
} | ||
intersect(...arrays) { | ||
const ret = (0, deno_std_collections_1.intersect)(this.val, ...arrays); | ||
return new Chain(ret); | ||
} | ||
join(separator) { | ||
return this.val.join(separator); | ||
} | ||
mapJoin(separator, transformer) { | ||
const mapped = this.map(transformer); | ||
return mapped.join(separator); | ||
} | ||
last() { | ||
var _a; | ||
return (_a = this.lastOrNull()) !== null && _a !== void 0 ? _a : (0, _1.error)("No last element found"); | ||
} | ||
lastOrNull() { | ||
const last = this.val[this.val.length - 1]; | ||
return last; | ||
} | ||
map(transformer) { | ||
const mapped = this.val.map(transformer); | ||
return new Chain(mapped); | ||
} | ||
mapAsync(transformer) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const ret = yield Promise.all(this.val.map(transformer)); | ||
return new Chain(ret); | ||
}); | ||
} | ||
mapNotNullish(transformer) { | ||
const ret = (0, deno_std_collections_1.mapNotNullish)(this.val, transformer); | ||
return new Chain(ret); | ||
} | ||
maxBy(selector) { | ||
// this is save because maxBy is overloaded too | ||
return (0, deno_std_collections_1.maxBy)(this.val, selector); | ||
} | ||
maxOf(selector) { | ||
if (this.val.length === 0) | ||
return undefined; | ||
let max = selector(this.val[0]); | ||
for (const el of this.val) { | ||
const selected = selector(el); | ||
if (selected > max) | ||
max = selected; | ||
} | ||
return max; | ||
} | ||
maxWith(comparator) { | ||
return (0, deno_std_collections_1.maxWith)(this.val, comparator); | ||
} | ||
minBy(selector) { | ||
// this is save because minBy is overloaded too | ||
return (0, deno_std_collections_1.minBy)(this.val, selector); | ||
} | ||
minOf(selector) { | ||
if (this.val.length === 0) | ||
return undefined; | ||
let min = selector(this.val[0]); | ||
for (const el of this.val) { | ||
const selected = selector(el); | ||
if (selected < min) | ||
min = selected; | ||
} | ||
return min; | ||
} | ||
minWith(comparator) { | ||
return (0, deno_std_collections_1.minWith)(this.val, comparator); | ||
} | ||
partition(predicate) { | ||
const [left, right] = (0, deno_std_collections_1.partition)(this.val, predicate); | ||
return [new Chain(left), new Chain(right)]; | ||
} | ||
permutations() { | ||
return new Chain((0, deno_std_collections_1.permutations)(this.val)); | ||
} | ||
reduce(reducer, initial) { | ||
return this.val.reduce(reducer, initial); | ||
} | ||
reduceRight(reducer, initial) { | ||
return this.val.reduceRight(reducer, initial); | ||
} | ||
reverse() { | ||
return new Chain([...this.val].reverse()); | ||
} | ||
runningReduce(reducer, initialValue) { | ||
const ret = (0, deno_std_collections_1.runningReduce)(this.val, reducer, initialValue); | ||
return new Chain(ret); | ||
} | ||
sample() { | ||
const ret = (0, deno_std_collections_1.sample)(this.val); | ||
return ret; | ||
} | ||
slice(start, end) { | ||
const ret = this.val.slice(start, end); | ||
return new Chain(ret); | ||
} | ||
slidingWindows(size, { step, partial }) { | ||
const ret = (0, deno_std_collections_1.slidingWindows)(this.val, size, { step, partial }); | ||
return new Chain(ret); | ||
} | ||
sort(compareFn) { | ||
return new Chain([...this.val].sort(compareFn)); | ||
} | ||
sortBy(selector) { | ||
// this is safe, because sortBy is overloaded as well | ||
const ret = (0, deno_std_collections_1.sortBy)(this.val, selector); | ||
return new Chain(ret); | ||
} | ||
sumOf(selector) { | ||
return (0, deno_std_collections_1.sumOf)(this.val, selector); | ||
} | ||
takeLastWhile(predicate) { | ||
return new Chain((0, deno_std_collections_1.takeLastWhile)(this.val, predicate)); | ||
} | ||
takeWhile(predicate) { | ||
return new Chain((0, deno_std_collections_1.takeWhile)(this.val, predicate)); | ||
} | ||
union(...arrays) { | ||
return new Chain((0, deno_std_collections_1.union)(this.val, ...arrays)); | ||
} | ||
unzip() { | ||
const [left, right] = (0, deno_std_collections_1.unzip)(this.val); | ||
return [new Chain(left), new Chain(right)]; | ||
} | ||
withoutAll(values) { | ||
const ret = (0, deno_std_collections_1.withoutAll)(this.val, values); | ||
return new Chain(ret); | ||
} | ||
zip(withArray) { | ||
return new Chain((0, deno_std_collections_1.zip)(this.val, withArray)); | ||
} | ||
} | ||
exports.Chain = Chain; | ||
//# sourceMappingURL=collections.js.map |
@@ -33,3 +33,3 @@ "use strict"; | ||
getTotalElapsedTimeInMs() { | ||
return (0, collections_1.sumOf)(this.tasks, (it) => { var _a; return (_a = it.elapsed) !== null && _a !== void 0 ? _a : 0; }); | ||
return (0, collections_1.chain)(this.tasks).sumOf((it) => { var _a; return (_a = it.elapsed) !== null && _a !== void 0 ? _a : 0; }); | ||
} | ||
@@ -36,0 +36,0 @@ toString() { |
@@ -0,1 +1,2 @@ | ||
import "./collections"; | ||
/** | ||
@@ -2,0 +3,0 @@ * tableToString will convert an array of records into a nicely formatted tableRow |
@@ -5,2 +5,3 @@ "use strict"; | ||
const range_1 = require("./range"); | ||
require("./collections"); | ||
const collections_1 = require("./collections"); | ||
@@ -36,4 +37,5 @@ function tableRow(row, columns, columnLengths) { | ||
}); | ||
const columnLength = (0, collections_1.chain)(columnLengths).sumOf((it) => it + 1) + 1; | ||
const border = " " + | ||
(0, range_1.range)(0, (0, collections_1.sumOf)(columnLengths, (it) => it + 1) + 1) | ||
(0, range_1.range)(0, columnLength) | ||
.map((_) => "-") | ||
@@ -40,0 +42,0 @@ .join(""); |
{ | ||
"name": "@opencreek/ext", | ||
"version": "2.0.0--canary.21.3702576932.0", | ||
"version": "2.0.0--canary.22.3712435423.0", | ||
"description": "", | ||
@@ -5,0 +5,0 @@ "main": "build/index.js", |
@@ -1,21 +0,560 @@ | ||
export * from "@opencreek/deno-std-collections" | ||
import { | ||
chunk, | ||
distinct, | ||
distinctBy, | ||
dropLastWhile, | ||
dropWhile, | ||
findLast, | ||
findLastIndex, | ||
findSingle, | ||
firstNotNullishOf, | ||
intersect, | ||
mapNotNullish, | ||
maxBy, | ||
maxWith, | ||
minBy, | ||
minWith, | ||
partition, | ||
permutations, | ||
runningReduce, | ||
sample, | ||
slidingWindows, | ||
sortBy, | ||
sumOf, | ||
takeLastWhile, | ||
takeWhile, | ||
union, | ||
unzip, | ||
withoutAll, | ||
zip, | ||
} from "@opencreek/deno-std-collections" | ||
import { error } from "." | ||
export function filterNotNullish<T>(arr: Array<T>): Array<NonNullable<T>> { | ||
return arr.filter((it): it is NonNullable<T> => it != null) | ||
type PairSplit<T> = T extends [infer F, infer L] ? [Chain<F>, Chain<L>] : never | ||
type IfString<T, U> = T extends string ? U : never | ||
type FlattenChain<T> = T extends Chain<infer U> ? Chain<U> : never | ||
export function objChain<K extends string | number | symbol, T>( | ||
value: Record<K, T> | ObjectChain<K, T> | Chain<readonly [K, T]> | ||
): ObjectChain<K, T> { | ||
if (value instanceof ObjectChain) { | ||
return value | ||
} | ||
if (value instanceof Chain) { | ||
return new ObjectChain(Object.fromEntries(value.value())) as ObjectChain< | ||
K, | ||
T | ||
> | ||
} | ||
return new ObjectChain(value) | ||
} | ||
export async function mapAsync<T, U>( | ||
arr: Array<T>, | ||
f: (e: T, index: number, array: Array<T>) => Promise<U> | ||
): Promise<Array<U>> { | ||
return Promise.all(arr.map(f)) | ||
export function chain<T>( | ||
value: ReadonlyArray<T> | Chain<T> | Iterable<T> | ||
): Chain<T> { | ||
if (value instanceof Chain) return value | ||
if (Array.isArray(value)) return new Chain(value) | ||
return new Chain([...value]) | ||
} | ||
export async function filterAsync<T>( | ||
arr: Array<T>, | ||
f: (e: T, index: number, array: Array<T>) => Promise<boolean> | ||
): Promise<Array<T>> { | ||
const includes = await mapAsync(arr, f) | ||
export class ObjectChain<K extends string | number | symbol, T> { | ||
constructor(private val: Record<K, T>) {} | ||
return arr.filter((_, index) => includes[index]) | ||
value(): Record<K, T> { | ||
return this.val | ||
} | ||
keys(): Chain<K> { | ||
return new Chain(Object.keys(this.val)) as Chain<K> | ||
} | ||
values(): Chain<T> { | ||
return new Chain(Object.values(this.val)) | ||
} | ||
mapKeys<U extends string | number | symbol>( | ||
transformer: (key: K) => U | ||
): ObjectChain<U, T> { | ||
const entries = Object.entries(this.val) as [K, T][] | ||
const mapped = entries.map(([k, v]) => { | ||
return [transformer(k), v] | ||
}) | ||
return new ObjectChain(Object.fromEntries(mapped)) | ||
} | ||
mapValues<V>(transformer: (value: T) => V): ObjectChain<K, V> { | ||
const entries = Object.entries(this.val) as [K, T][] | ||
const mapped = entries.map(([k, v]) => { | ||
return [k, transformer(v)] | ||
}) | ||
return new ObjectChain(Object.fromEntries(mapped)) | ||
} | ||
mapEntries<U extends string | number | symbol, V>( | ||
transformer: (key: K, value: T) => [U, V] | ||
): ObjectChain<U, V> { | ||
const entries = Object.entries(this.val) as [K, T][] | ||
const mapped = entries.map(([k, v]) => { | ||
return transformer(k, v) | ||
}) | ||
return new ObjectChain(Object.fromEntries(mapped)) as ObjectChain<U, V> | ||
} | ||
filterKeys(filter: (key: K) => boolean): ObjectChain<K, T> { | ||
const entries = Object.entries(this.val) as [K, T][] | ||
const filtered = entries.filter(([k, _]) => { | ||
return filter(k) | ||
}) | ||
return new ObjectChain(Object.fromEntries(filtered)) as ObjectChain<K, T> | ||
} | ||
filterValues(filter: (value: T) => boolean): ObjectChain<K, T> { | ||
const entries = Object.entries(this.val) as [K, T][] | ||
const filtered = entries.filter(([_, v]) => { | ||
return filter(v) | ||
}) | ||
return new ObjectChain(Object.fromEntries(filtered)) as ObjectChain<K, T> | ||
} | ||
filterEntries(filter: (key: K, value: T) => boolean): ObjectChain<K, T> { | ||
const entries = Object.entries(this.val) as [K, T][] | ||
const filtered = entries.filter(([k, v]) => { | ||
return filter(k, v) | ||
}) | ||
return new ObjectChain(Object.fromEntries(filtered)) as ObjectChain<K, T> | ||
} | ||
} | ||
export class Chain<T> { | ||
constructor(private val: ReadonlyArray<T>) {} | ||
value(): ReadonlyArray<T> { | ||
return this.val | ||
} | ||
associateBy<S extends string | number | symbol>( | ||
selector: (el: T) => S | ||
): ObjectChain<S, T> { | ||
const entries = this.map((m) => { | ||
return [selector(m), m] as const | ||
}) | ||
return objChain(entries) | ||
} | ||
associateWith<U>( | ||
selector: (key: string) => U | ||
): IfString<T, ObjectChain<string, U>> { | ||
const entries = this.map((el) => { | ||
return [ | ||
el as unknown as string, | ||
selector(el as unknown as string), | ||
] as const | ||
}) | ||
return objChain(entries) as IfString<T, ObjectChain<string, U>> | ||
} | ||
chunk(size: number): Chain<T[]> { | ||
const chunks = chunk(this.val, size) | ||
return new Chain(chunks) | ||
} | ||
distinct(): Chain<T> { | ||
const unique = distinct(this.val) | ||
return new Chain(unique) | ||
} | ||
distinctBy<D>(selector: (el: T) => D): Chain<T> { | ||
const unique = distinctBy(this.val, selector) | ||
return new Chain(unique) | ||
} | ||
dropLastWhile(predicate: (el: T) => boolean): Chain<T> { | ||
const dropped = dropLastWhile(this.val, predicate) | ||
return new Chain(dropped) | ||
} | ||
dropWhile(predicate: (el: T) => boolean): Chain<T> { | ||
const dropped = dropWhile(this.val, predicate) | ||
return new Chain(dropped) | ||
} | ||
every<S extends T>( | ||
predicate: (el: T, index: number, array: ReadonlyArray<T>) => el is S | ||
): this is Chain<S> | ||
every( | ||
predicate: (el: T, index: number, array: ReadonlyArray<T>) => boolean | ||
): boolean | ||
every( | ||
predicate: (el: T, index: number, array: ReadonlyArray<T>) => boolean | ||
): boolean { | ||
return this.val.every(predicate) | ||
} | ||
some( | ||
predicate: (value: T, index: number, array: ReadonlyArray<T>) => boolean | ||
): boolean { | ||
return this.val.some(predicate) | ||
} | ||
first(): T { | ||
return this.firstOrNull() ?? error("No first element found") | ||
} | ||
firstOrNull(): T | undefined { | ||
return this.val[0] | ||
} | ||
filter( | ||
filter: (el: T, index: number, array: ReadonlyArray<T>) => boolean | ||
): Chain<T> { | ||
const filtered = this.val.filter(filter) | ||
return new Chain(filtered) | ||
} | ||
async filterAsync( | ||
predicate: ( | ||
el: T, | ||
index: number, | ||
array: ReadonlyArray<T> | ||
) => Promise<boolean> | ||
): Promise<Chain<T>> { | ||
const includes = await this.mapAsync(predicate) | ||
return this.filter((_, index) => includes.val[index]) | ||
} | ||
filterNotNullish(): Chain<NonNullable<T>> { | ||
return this.filter((it) => it != null) as Chain<NonNullable<T>> | ||
} | ||
find<S extends T>( | ||
predicate: (el: T, index: number, array: ReadonlyArray<T>) => el is S | ||
): S | undefined { | ||
return this.val.find(predicate) | ||
} | ||
findIndex( | ||
predicate: (el: T, index: number, array: ReadonlyArray<T>) => boolean | ||
): number | undefined { | ||
const ret = this.val.findIndex(predicate) | ||
if (ret === -1) return undefined | ||
return ret | ||
} | ||
findLast(predicate: (el: T) => boolean): T | undefined { | ||
return findLast(this.val, predicate) | ||
} | ||
findLastIndex(predicate: (el: T) => boolean): number | undefined { | ||
return findLastIndex(this.val, predicate) | ||
} | ||
findSingle(predicate: (el: T) => boolean): T | undefined { | ||
return findSingle(this.val, predicate) | ||
} | ||
firstNotNullishOf<O>( | ||
selector: (item: T) => O | undefined | null | ||
): NonNullable<O> | undefined { | ||
return firstNotNullishOf(this.val, selector) | ||
} | ||
flatten(): FlattenChain<T> { | ||
const flattened = this.val.flatMap((it) => | ||
it instanceof Chain ? it.val : [] | ||
) | ||
return new Chain(flattened) as FlattenChain<T> | ||
} | ||
flatMap<U>( | ||
transformer: (el: T, index: number, array: ReadonlyArray<T>) => Chain<U> | ||
): Chain<U> { | ||
return this.map(transformer).flatten() | ||
} | ||
forEach( | ||
callback: (el: T, index: number, array: ReadonlyArray<T>) => void | ||
): void { | ||
this.map(callback) | ||
} | ||
groupBy<K extends string | symbol | number>( | ||
selector: (el: T) => K | ||
): ObjectChain<K, ReadonlyArray<T>> { | ||
const record = {} as Record<K, Array<T>> | ||
for (const el of this.val) { | ||
const key = selector(el) | ||
if (record[key] != null) { | ||
record[key]?.push(el) | ||
} else { | ||
record[key] = [el] | ||
} | ||
} | ||
return new ObjectChain(record) | ||
} | ||
indexOf(searchElement: T, fromIndex?: number): number | undefined { | ||
const ret = this.val.indexOf(searchElement, fromIndex) | ||
if (ret === -1) return undefined | ||
return ret | ||
} | ||
lastIndexOf(searchElement: T, fromIndex?: number): number | undefined { | ||
const ret = this.val.lastIndexOf(searchElement, fromIndex) | ||
if (ret === -1) return undefined | ||
return ret | ||
} | ||
includes(el: T, fromIndex?: number): boolean { | ||
return this.val.includes(el, fromIndex) | ||
} | ||
intersect(...arrays: (readonly T[])[]): Chain<T> { | ||
const ret = intersect(this.val, ...arrays) | ||
return new Chain(ret) | ||
} | ||
join(separator?: string): string { | ||
return this.val.join(separator) | ||
} | ||
mapJoin(separator: string, transformer: (el: T) => string): string { | ||
const mapped = this.map(transformer) | ||
return mapped.join(separator) | ||
} | ||
last(): T { | ||
return this.lastOrNull() ?? error("No last element found") | ||
} | ||
lastOrNull(): T | undefined { | ||
const last = this.val[this.val.length - 1] | ||
return last | ||
} | ||
map<U>( | ||
transformer: (el: T, index: number, array: ReadonlyArray<T>) => U | ||
): Chain<U> { | ||
const mapped = this.val.map(transformer) | ||
return new Chain(mapped) | ||
} | ||
async mapAsync<U>( | ||
transformer: (el: T, index: number, array: ReadonlyArray<T>) => Promise<U> | ||
): Promise<Chain<U>> { | ||
const ret = await Promise.all(this.val.map(transformer)) | ||
return new Chain(ret) | ||
} | ||
mapNotNullish<O>(transformer: (el: T) => O): Chain<NonNullable<O>> { | ||
const ret = mapNotNullish(this.val, transformer) | ||
return new Chain(ret) | ||
} | ||
maxBy(selector: (el: T) => string): T | undefined | ||
maxBy(selector: (el: T) => bigint): T | undefined | ||
maxBy(selector: (el: T) => number): T | undefined | ||
maxBy(selector: (el: T) => Date): T | undefined | ||
maxBy(selector: (el: T) => Date | number | bigint | string): T | undefined { | ||
// this is save because maxBy is overloaded too | ||
return maxBy(this.val, selector as (el: T) => string) | ||
} | ||
maxOf(selector: (el: T) => bigint): bigint | undefined | ||
maxOf(selector: (el: T) => number): number | undefined | ||
maxOf(selector: (el: T) => string): string | undefined | ||
maxOf(selector: (el: T) => Date): Date | undefined | ||
maxOf<R extends bigint | number | string | Date>( | ||
selector: (el: T) => R | ||
): R | undefined { | ||
if (this.val.length === 0) return undefined | ||
let max: R = selector(this.val[0]) | ||
for (const el of this.val) { | ||
const selected = selector(el) | ||
if (selected > max) max = selected | ||
} | ||
return max | ||
} | ||
maxWith(comparator: (a: T, b: T) => number): T | undefined { | ||
return maxWith(this.val, comparator) | ||
} | ||
minBy(selector: (el: T) => number): T | undefined | ||
minBy(selector: (el: T) => string): T | undefined | ||
minBy(selector: (el: T) => bigint): T | undefined | ||
minBy(selector: (el: T) => Date): T | undefined | ||
minBy(selector: (el: T) => Date | number | bigint | string): T | undefined { | ||
// this is save because minBy is overloaded too | ||
return minBy(this.val, selector as (el: T) => string) | ||
} | ||
minOf(selector: (el: T) => bigint): bigint | undefined | ||
minOf(selector: (el: T) => number): number | undefined | ||
minOf(selector: (el: T) => string): string | undefined | ||
minOf(selector: (el: T) => Date): Date | undefined | ||
minOf<R extends bigint | number | string | Date>( | ||
selector: (el: T) => R | ||
): R | undefined { | ||
if (this.val.length === 0) return undefined | ||
let min: R = selector(this.val[0]) | ||
for (const el of this.val) { | ||
const selected = selector(el) | ||
if (selected < min) min = selected | ||
} | ||
return min | ||
} | ||
minWith(comparator: (a: T, b: T) => number): T | undefined { | ||
return minWith(this.val, comparator) | ||
} | ||
partition(predicate: (el: T) => boolean): [Chain<T>, Chain<T>] { | ||
const [left, right] = partition(this.val, predicate) | ||
return [new Chain(left), new Chain(right)] | ||
} | ||
permutations(): Chain<T[]> { | ||
return new Chain(permutations(this.val)) | ||
} | ||
reduce( | ||
reducer: ( | ||
accumulator: T, | ||
current: T, | ||
index: number, | ||
array: ReadonlyArray<T> | ||
) => T | ||
): T | ||
reduce( | ||
reducer: ( | ||
accumulator: T, | ||
current: T, | ||
index: number, | ||
array: ReadonlyArray<T> | ||
) => T, | ||
initial: T | ||
): T | ||
reduce<O>( | ||
reducer: ( | ||
accumulator: O, | ||
current: T, | ||
index: number, | ||
array: ReadonlyArray<T> | ||
) => O, | ||
initial: O | ||
): O | ||
reduce<O>( | ||
reducer: ( | ||
accumulator: O, | ||
current: T, | ||
index: number, | ||
array: ReadonlyArray<T> | ||
) => O, | ||
initial?: O | ||
): O { | ||
return this.val.reduce<O>(reducer, initial as O) | ||
} | ||
reduceRight( | ||
reducer: ( | ||
accumulator: T, | ||
current: T, | ||
index: number, | ||
array: ReadonlyArray<T> | ||
) => T | ||
): T | ||
reduceRight( | ||
reducer: ( | ||
accumulator: T, | ||
current: T, | ||
index: number, | ||
array: ReadonlyArray<T> | ||
) => T, | ||
initial: T | ||
): T | ||
reduceRight<O>( | ||
reducer: ( | ||
accumulator: O, | ||
current: T, | ||
index: number, | ||
array: ReadonlyArray<T> | ||
) => O, | ||
initial: O | ||
): O | ||
reduceRight<O>( | ||
reducer: ( | ||
accumulator: O, | ||
current: T, | ||
index: number, | ||
array: ReadonlyArray<T> | ||
) => O, | ||
initial?: O | ||
): O { | ||
return this.val.reduceRight<O>(reducer, initial as O) | ||
} | ||
reverse(): Chain<T> { | ||
return new Chain([...this.val].reverse()) | ||
} | ||
runningReduce<O>( | ||
reducer: (accumulator: O, current: T) => O, | ||
initialValue: O | ||
): Chain<O> { | ||
const ret = runningReduce(this.val, reducer, initialValue) | ||
return new Chain(ret) | ||
} | ||
sample(): T | undefined { | ||
const ret = sample(this.val) | ||
return ret | ||
} | ||
slice(start?: number, end?: number): Chain<T> { | ||
const ret = this.val.slice(start, end) | ||
return new Chain(ret) | ||
} | ||
slidingWindows( | ||
size: number, | ||
{ step, partial }: { step: number; partial: boolean } | ||
): Chain<T[]> { | ||
const ret = slidingWindows(this.val, size, { step, partial }) | ||
return new Chain(ret) | ||
} | ||
sort(compareFn?: (a: T, b: T) => number): Chain<T> { | ||
return new Chain([...this.val].sort(compareFn)) | ||
} | ||
sortBy(selector: (el: T) => Date): Chain<T> | ||
sortBy(selector: (el: T) => bigint): Chain<T> | ||
sortBy(selector: (el: T) => string): Chain<T> | ||
sortBy(selector: (el: T) => number): Chain<T> | ||
sortBy(selector: (el: T) => Date | bigint | string | number): Chain<T> { | ||
// this is safe, because sortBy is overloaded as well | ||
const ret = sortBy(this.val, selector as (el: T) => number) | ||
return new Chain(ret) | ||
} | ||
sumOf(selector: (el: T) => number): number { | ||
return sumOf(this.val, selector) | ||
} | ||
takeLastWhile(predicate: (el: T) => boolean): Chain<T> { | ||
return new Chain(takeLastWhile(this.val, predicate)) | ||
} | ||
takeWhile(predicate: (el: T) => boolean): Chain<T> { | ||
return new Chain(takeWhile(this.val, predicate)) | ||
} | ||
union(...arrays: (readonly T[])[]): Chain<T> { | ||
return new Chain(union(this.val, ...arrays)) | ||
} | ||
unzip(): PairSplit<T> { | ||
const [left, right] = unzip(this.val as unknown as ReadonlyArray<[T, T]>) | ||
return [new Chain(left), new Chain(right)] as PairSplit<T> | ||
} | ||
withoutAll(values: readonly T[]): Chain<T> { | ||
const ret = withoutAll(this.val, values) | ||
return new Chain(ret) | ||
} | ||
zip<U>(withArray: readonly U[]): Chain<[T, U]> { | ||
return new Chain(zip(this.val, withArray)) | ||
} | ||
} |
import { tableToString } from "./table" | ||
import { sumOf } from "./collections" | ||
import { chain } from "./collections" | ||
@@ -43,3 +43,3 @@ type Task = { | ||
getTotalElapsedTimeInMs(): number { | ||
return sumOf(this.tasks, (it) => it.elapsed ?? 0) | ||
return chain(this.tasks).sumOf((it) => it.elapsed ?? 0) | ||
} | ||
@@ -46,0 +46,0 @@ |
import { range } from "./range" | ||
import { sumOf } from "./collections" | ||
import "./collections" | ||
import { chain } from "./collections" | ||
@@ -48,5 +49,7 @@ function tableRow<T extends Record<string | number | symbol, unknown>>( | ||
const columnLength = chain(columnLengths).sumOf((it) => it + 1) + 1 | ||
const border = | ||
" " + | ||
range(0, sumOf(columnLengths, (it) => it + 1) + 1) | ||
range(0, columnLength) | ||
.map((_) => "-") | ||
@@ -53,0 +56,0 @@ .join("") |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
106238
1925