This commit is contained in:
@@ -30,4 +30,4 @@ jobs:
|
|||||||
- name: Publish
|
- name: Publish
|
||||||
run: npm publish
|
run: npm publish
|
||||||
env:
|
env:
|
||||||
INFENDRO__TOKEN: ${{ secrets.token }}
|
TOKEN: ${{ secrets.token }}
|
||||||
|
|||||||
2
.npmrc
2
.npmrc
@@ -1,2 +1,2 @@
|
|||||||
@infendro:registry=https://git.infendro.com/api/packages/Infendro/npm/
|
@infendro:registry=https://git.infendro.com/api/packages/Infendro/npm/
|
||||||
//git.infendro.com/api/packages/Infendro/npm/:_authToken="${INFENDRO__TOKEN}"
|
//git.infendro.com/api/packages/Infendro/npm/:_authToken="${TOKEN}"
|
||||||
|
|||||||
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,11 +1,11 @@
|
|||||||
{
|
{
|
||||||
"name": "@infendro/sequence",
|
"name": "@infendro/collection",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "@infendro/sequence",
|
"name": "@infendro/collection",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"typescript": "^6.0.3"
|
"typescript": "^6.0.3"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "@infendro/sequence",
|
"name": "@infendro/collection",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "tsc"
|
"build": "tsc"
|
||||||
|
|||||||
434
src/collection.ts
Normal file
434
src/collection.ts
Normal file
@@ -0,0 +1,434 @@
|
|||||||
|
import {all} from "./collection/all";
|
||||||
|
import {any} from "./collection/any";
|
||||||
|
import {associate} from "./collection/associate";
|
||||||
|
import {associateBy} from "./collection/associateBy";
|
||||||
|
import {associateWith} from "./collection/associateWith";
|
||||||
|
import {average} from "./collection/average";
|
||||||
|
import {averageBy} from "./collection/averageBy";
|
||||||
|
import {averageByOrNull} from "./collection/averageByOrNull";
|
||||||
|
import {averageOrNull} from "./collection/averageOrNull";
|
||||||
|
import {chunked} from "./collection/chunked";
|
||||||
|
import {contains} from "./collection/contains";
|
||||||
|
import {containsAll} from "./collection/containsAll";
|
||||||
|
import {count} from "./collection/count";
|
||||||
|
import {distinct} from "./collection/distinct";
|
||||||
|
import {distinctBy} from "./collection/distinctBy";
|
||||||
|
import {drop} from "./collection/drop";
|
||||||
|
import {dropUntil} from "./collection/dropUntil";
|
||||||
|
import {dropWhile} from "./collection/dropWhile";
|
||||||
|
import {filter} from "./collection/filter";
|
||||||
|
import {first} from "./collection/first";
|
||||||
|
import {firstOrNull} from "./collection/firstOrNull";
|
||||||
|
import {flatMap} from "./collection/flatMap";
|
||||||
|
import {flatten} from "./collection/flatten";
|
||||||
|
import {fold} from "./collection/fold";
|
||||||
|
import {forEach} from "./collection/forEach";
|
||||||
|
import {get} from "./collection/get";
|
||||||
|
import {getOrNull} from "./collection/getOrNull";
|
||||||
|
import {groupBy} from "./collection/groupBy";
|
||||||
|
import {indices} from "./collection/indices";
|
||||||
|
import {intersect} from "./collection/intersect";
|
||||||
|
import {isEmpty} from "./collection/isEmpty";
|
||||||
|
import {isNotEmpty} from "./collection/isNotEmpty";
|
||||||
|
import {joinToString} from "./collection/joinToString";
|
||||||
|
import {last} from "./collection/last";
|
||||||
|
import {lastOrNull} from "./collection/lastOrNull";
|
||||||
|
import {map} from "./collection/map";
|
||||||
|
import {mapNotNull} from "./collection/mapNotNull";
|
||||||
|
import {max} from "./collection/max";
|
||||||
|
import {maxBy} from "./collection/maxBy";
|
||||||
|
import {maxByOrNull} from "./collection/maxByOrNull";
|
||||||
|
import {maxOf} from "./collection/maxOf";
|
||||||
|
import {maxOfOrNull} from "./collection/maxOfOrNull";
|
||||||
|
import {maxOrNull} from "./collection/maxOrNull";
|
||||||
|
import {maxWith} from "./collection/maxWith";
|
||||||
|
import {maxWithOrNull} from "./collection/maxWithOrNull";
|
||||||
|
import {min} from "./collection/min";
|
||||||
|
import {minBy} from "./collection/minBy";
|
||||||
|
import {minByOrNull} from "./collection/minByOrNull";
|
||||||
|
import {minOf} from "./collection/minOf";
|
||||||
|
import {minOfOrNull} from "./collection/minOfOrNull";
|
||||||
|
import {minOrNull} from "./collection/minOrNull";
|
||||||
|
import {minWith} from "./collection/minWith";
|
||||||
|
import {minWithOrNull} from "./collection/minWithOrNull";
|
||||||
|
import {minus} from "./collection/minus";
|
||||||
|
import {none} from "./collection/none";
|
||||||
|
import {onEach} from "./collection/onEach";
|
||||||
|
import {partition} from "./collection/partition";
|
||||||
|
import {plus} from "./collection/plus";
|
||||||
|
import {reduce} from "./collection/reduce";
|
||||||
|
import {reduceOrNull} from "./collection/reduceOrNull";
|
||||||
|
import {reversed} from "./collection/reversed";
|
||||||
|
import {scan} from "./collection/scan";
|
||||||
|
import {single} from "./collection/single";
|
||||||
|
import {singleOrNull} from "./collection/singleOrNull";
|
||||||
|
import {slice} from "./collection/slice";
|
||||||
|
import {sorted} from "./collection/sorted";
|
||||||
|
import {sortedBy} from "./collection/sortedBy";
|
||||||
|
import {sortedWith} from "./collection/sortedWith";
|
||||||
|
import {sum} from "./collection/sum";
|
||||||
|
import {sumBy} from "./collection/sumBy";
|
||||||
|
import {take} from "./collection/take";
|
||||||
|
import {takeUntil} from "./collection/takeUntil";
|
||||||
|
import {takeWhile} from "./collection/takeWhile";
|
||||||
|
import {toArray} from "./collection/toArray";
|
||||||
|
import {toMap} from "./collection/toMap";
|
||||||
|
import {toSet} from "./collection/toSet";
|
||||||
|
import {unzip} from "./collection/unzip";
|
||||||
|
import {windowed} from "./collection/windowed";
|
||||||
|
import {withIndex} from "./collection/withIndex";
|
||||||
|
import {zip} from "./collection/zip";
|
||||||
|
|
||||||
|
export type Collection<T> = {
|
||||||
|
[Symbol.iterator](): Iterator<T>
|
||||||
|
|
||||||
|
toArray(): T[]
|
||||||
|
toSet(): Set<T>
|
||||||
|
toMap<K, V>(this: Collection<[K, V]>): Map<K, V>
|
||||||
|
|
||||||
|
onEach(action: (it: T) => void): Collection<T>
|
||||||
|
forEach(action: (it: T) => void): void
|
||||||
|
|
||||||
|
isEmpty(): boolean
|
||||||
|
isNotEmpty(): boolean
|
||||||
|
count(predicate?: (it: T) => boolean): number
|
||||||
|
|
||||||
|
indices(): Collection<number>
|
||||||
|
withIndex(): Collection<[number, T]>
|
||||||
|
|
||||||
|
contains(item: T): boolean
|
||||||
|
containsAll(items: Iterable<T>): boolean
|
||||||
|
any(predicate: (it: T) => boolean): boolean
|
||||||
|
all(predicate: (it: T) => boolean): boolean
|
||||||
|
none(predicate: (it: T) => boolean): boolean
|
||||||
|
|
||||||
|
get(index: number): T
|
||||||
|
getOrNull(index: number): T | null
|
||||||
|
first(predicate?: (it: T) => boolean): T
|
||||||
|
firstOrNull(predicate?: (it: T) => boolean): T | null
|
||||||
|
last(predicate?: (it: T) => boolean): T
|
||||||
|
lastOrNull(predicate?: (it: T) => boolean): T | null
|
||||||
|
single(predicate?: (it: T) => boolean): T
|
||||||
|
singleOrNull(predicate?: (it: T) => boolean): T | null
|
||||||
|
|
||||||
|
reduce(accumulate: (acc: T, it: T) => T): T
|
||||||
|
reduceOrNull(accumulate: (acc: T, it: T) => T): T | null
|
||||||
|
fold<R>(initial: R, accumulate: (acc: R, it: T) => R): R
|
||||||
|
scan<R>(initial: R, accumulate: (acc: R, it: T) => R): Collection<R>
|
||||||
|
sum(this: Collection<number>): number
|
||||||
|
sumBy(transform: (it: T) => number): number
|
||||||
|
average(this: Collection<number>): number
|
||||||
|
averageOrNull(this: Collection<number>): number | null
|
||||||
|
averageBy(transform: (it: T) => number): number
|
||||||
|
averageByOrNull(transform: (it: T) => number): number | null
|
||||||
|
|
||||||
|
min(this: Collection<number>): number
|
||||||
|
minOrNull(this: Collection<number>): number | null
|
||||||
|
minWith(compare: (a: T, b: T) => number): T
|
||||||
|
minWithOrNull(compare: (a: T, b: T) => number): T | null
|
||||||
|
minBy(transform: (it: T) => number): T
|
||||||
|
minByOrNull(transform: (it: T) => number): T | null
|
||||||
|
minOf(transform: (it: T) => number): number
|
||||||
|
minOfOrNull(transform: (it: T) => number): number | null
|
||||||
|
|
||||||
|
max(this: Collection<number>): number
|
||||||
|
maxOrNull(this: Collection<number>): number | null
|
||||||
|
maxWith(compare: (a: T, b: T) => number): T
|
||||||
|
maxWithOrNull(compare: (a: T, b: T) => number): T | null
|
||||||
|
maxBy(transform: (it: T) => number): T
|
||||||
|
maxByOrNull(transform: (it: T) => number): T | null
|
||||||
|
maxOf(transform: (it: T) => number): number
|
||||||
|
maxOfOrNull(transform: (it: T) => number): number | null
|
||||||
|
|
||||||
|
joinToString(separator: string, transform?: (it: T) => string): string
|
||||||
|
|
||||||
|
plus(items: Iterable<T>): Collection<T>
|
||||||
|
minus(items: Iterable<T>): Collection<T>
|
||||||
|
intersect(items: Iterable<T>): Collection<T>
|
||||||
|
|
||||||
|
filter<R extends T>(predicate: (it: T) => it is R): Collection<R>
|
||||||
|
filter(predicate: (it: T) => boolean): Collection<T>
|
||||||
|
partition(predicate: (it: T) => boolean): [T[], T[]]
|
||||||
|
distinct(): Collection<T>
|
||||||
|
distinctBy<K>(transform: (it: T) => K): Collection<T>
|
||||||
|
|
||||||
|
drop(count: number): Collection<T>
|
||||||
|
dropWhile(predicate: (it: T) => boolean): Collection<T>
|
||||||
|
dropUntil(predicate: (it: T) => boolean): Collection<T>
|
||||||
|
take(count: number): Collection<T>
|
||||||
|
takeWhile(predicate: (it: T) => boolean): Collection<T>
|
||||||
|
takeUntil(predicate: (it: T) => boolean): Collection<T>
|
||||||
|
slice(start: number, end?: number): Collection<T>
|
||||||
|
|
||||||
|
map<R>(transform: (it: T) => R): Collection<R>
|
||||||
|
mapNotNull<R>(transform: (it: T) => R | null): Collection<R>
|
||||||
|
flatten<R>(this: Collection<Iterable<R>>): Collection<R>
|
||||||
|
flatMap<R>(transform: (it: T) => Iterable<R>): Collection<R>
|
||||||
|
|
||||||
|
groupBy<K>(transform: (it: T) => K): Collection<[K, T[]]>
|
||||||
|
associate<K, V>(transform: (it: T) => [K, V]): Collection<[K, V]>
|
||||||
|
associateBy<K>(transform: (it: T) => K): Collection<[K, T]>
|
||||||
|
associateWith<V>(transform: (it: T) => V): Collection<[T, V]>
|
||||||
|
zip<B>(items: Iterable<B>): Collection<[T, B]>
|
||||||
|
unzip<A, B>(this: Collection<[A, B]>): [A[], B[]]
|
||||||
|
|
||||||
|
windowed(size: number, step?: number, partial?: boolean): Collection<T[]>
|
||||||
|
chunked(size: number): Collection<T[]>
|
||||||
|
|
||||||
|
reversed(): Collection<T>
|
||||||
|
sorted(this: Collection<number>): Collection<number>
|
||||||
|
sortedWith(compare: (a: T, b: T) => number): Collection<T>
|
||||||
|
sortedBy(transform: (it: T) => number): Collection<T>
|
||||||
|
}
|
||||||
|
|
||||||
|
export function collection<T>(value: Iterable<T>): Collection<T> {
|
||||||
|
return wrap([...value]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function wrap<T>(value: T[]): Collection<T> {
|
||||||
|
return {
|
||||||
|
[Symbol.iterator]() {
|
||||||
|
return value[Symbol.iterator]();
|
||||||
|
},
|
||||||
|
toArray() {
|
||||||
|
return toArray(value);
|
||||||
|
},
|
||||||
|
toSet() {
|
||||||
|
return toSet(value);
|
||||||
|
},
|
||||||
|
toMap<K, V>() {
|
||||||
|
return toMap(value as [K, V][]);
|
||||||
|
},
|
||||||
|
onEach(action) {
|
||||||
|
return wrap(onEach(value, action));
|
||||||
|
},
|
||||||
|
forEach(action) {
|
||||||
|
forEach(value, action);
|
||||||
|
},
|
||||||
|
isEmpty() {
|
||||||
|
return isEmpty(value);
|
||||||
|
},
|
||||||
|
isNotEmpty() {
|
||||||
|
return isNotEmpty(value);
|
||||||
|
},
|
||||||
|
count(predicate) {
|
||||||
|
return count(value, predicate);
|
||||||
|
},
|
||||||
|
indices() {
|
||||||
|
return wrap(indices(value));
|
||||||
|
},
|
||||||
|
withIndex() {
|
||||||
|
return wrap(withIndex(value));
|
||||||
|
},
|
||||||
|
contains(item) {
|
||||||
|
return contains(value, item);
|
||||||
|
},
|
||||||
|
containsAll(items) {
|
||||||
|
return containsAll(value, items);
|
||||||
|
},
|
||||||
|
any(predicate) {
|
||||||
|
return any(value, predicate);
|
||||||
|
},
|
||||||
|
all(predicate) {
|
||||||
|
return all(value, predicate);
|
||||||
|
},
|
||||||
|
none(predicate) {
|
||||||
|
return none(value, predicate);
|
||||||
|
},
|
||||||
|
get(index) {
|
||||||
|
return get(value, index);
|
||||||
|
},
|
||||||
|
getOrNull(index) {
|
||||||
|
return getOrNull(value, index);
|
||||||
|
},
|
||||||
|
first(predicate) {
|
||||||
|
return first(value, predicate);
|
||||||
|
},
|
||||||
|
firstOrNull(predicate) {
|
||||||
|
return firstOrNull(value, predicate);
|
||||||
|
},
|
||||||
|
last(predicate) {
|
||||||
|
return last(value, predicate);
|
||||||
|
},
|
||||||
|
lastOrNull(predicate) {
|
||||||
|
return lastOrNull(value, predicate);
|
||||||
|
},
|
||||||
|
single(predicate) {
|
||||||
|
return single(value, predicate);
|
||||||
|
},
|
||||||
|
singleOrNull(predicate) {
|
||||||
|
return singleOrNull(value, predicate);
|
||||||
|
},
|
||||||
|
reduce(accumulate) {
|
||||||
|
return reduce(value, accumulate);
|
||||||
|
},
|
||||||
|
reduceOrNull(accumulate) {
|
||||||
|
return reduceOrNull(value, accumulate);
|
||||||
|
},
|
||||||
|
fold(initial, accumulate) {
|
||||||
|
return fold(value, initial, accumulate);
|
||||||
|
},
|
||||||
|
scan(initial, accumulate) {
|
||||||
|
return wrap(scan(value, initial, accumulate));
|
||||||
|
},
|
||||||
|
sum() {
|
||||||
|
return sum(value as number[]);
|
||||||
|
},
|
||||||
|
sumBy(transform) {
|
||||||
|
return sumBy(value, transform);
|
||||||
|
},
|
||||||
|
average() {
|
||||||
|
return average(value as number[]);
|
||||||
|
},
|
||||||
|
averageOrNull() {
|
||||||
|
return averageOrNull(value as number[]);
|
||||||
|
},
|
||||||
|
averageBy(transform) {
|
||||||
|
return averageBy(value, transform);
|
||||||
|
},
|
||||||
|
averageByOrNull(transform) {
|
||||||
|
return averageByOrNull(value, transform);
|
||||||
|
},
|
||||||
|
min() {
|
||||||
|
return min(value as number[]);
|
||||||
|
},
|
||||||
|
minOrNull() {
|
||||||
|
return minOrNull(value as number[]);
|
||||||
|
},
|
||||||
|
minWith(compare) {
|
||||||
|
return minWith(value, compare);
|
||||||
|
},
|
||||||
|
minWithOrNull(compare) {
|
||||||
|
return minWithOrNull(value, compare);
|
||||||
|
},
|
||||||
|
minBy(transform) {
|
||||||
|
return minBy(value, transform);
|
||||||
|
},
|
||||||
|
minByOrNull(transform) {
|
||||||
|
return minByOrNull(value, transform);
|
||||||
|
},
|
||||||
|
minOf(transform) {
|
||||||
|
return minOf(value, transform);
|
||||||
|
},
|
||||||
|
minOfOrNull(transform) {
|
||||||
|
return minOfOrNull(value, transform);
|
||||||
|
},
|
||||||
|
max() {
|
||||||
|
return max(value as number[]);
|
||||||
|
},
|
||||||
|
maxOrNull() {
|
||||||
|
return maxOrNull(value as number[]);
|
||||||
|
},
|
||||||
|
maxWith(compare) {
|
||||||
|
return maxWith(value, compare);
|
||||||
|
},
|
||||||
|
maxWithOrNull(compare) {
|
||||||
|
return maxWithOrNull(value, compare);
|
||||||
|
},
|
||||||
|
maxBy(transform) {
|
||||||
|
return maxBy(value, transform);
|
||||||
|
},
|
||||||
|
maxByOrNull(transform) {
|
||||||
|
return maxByOrNull(value, transform);
|
||||||
|
},
|
||||||
|
maxOf(transform) {
|
||||||
|
return maxOf(value, transform);
|
||||||
|
},
|
||||||
|
maxOfOrNull(transform) {
|
||||||
|
return maxOfOrNull(value, transform);
|
||||||
|
},
|
||||||
|
joinToString(separator, transform) {
|
||||||
|
return joinToString(value, separator, transform);
|
||||||
|
},
|
||||||
|
plus(items) {
|
||||||
|
return wrap(plus(value, items));
|
||||||
|
},
|
||||||
|
minus(items) {
|
||||||
|
return wrap(minus(value, items));
|
||||||
|
},
|
||||||
|
intersect(items) {
|
||||||
|
return wrap(intersect(value, items));
|
||||||
|
},
|
||||||
|
filter(predicate: (it: T) => boolean) {
|
||||||
|
return wrap(filter(value, predicate));
|
||||||
|
},
|
||||||
|
partition(predicate) {
|
||||||
|
return partition(value, predicate);
|
||||||
|
},
|
||||||
|
distinct() {
|
||||||
|
return wrap(distinct(value));
|
||||||
|
},
|
||||||
|
distinctBy(transform) {
|
||||||
|
return wrap(distinctBy(value, transform));
|
||||||
|
},
|
||||||
|
drop(count) {
|
||||||
|
return wrap(drop(value, count));
|
||||||
|
},
|
||||||
|
dropWhile(predicate) {
|
||||||
|
return wrap(dropWhile(value, predicate));
|
||||||
|
},
|
||||||
|
dropUntil(predicate) {
|
||||||
|
return wrap(dropUntil(value, predicate));
|
||||||
|
},
|
||||||
|
take(count) {
|
||||||
|
return wrap(take(value, count));
|
||||||
|
},
|
||||||
|
takeWhile(predicate) {
|
||||||
|
return wrap(takeWhile(value, predicate));
|
||||||
|
},
|
||||||
|
takeUntil(predicate) {
|
||||||
|
return wrap(takeUntil(value, predicate));
|
||||||
|
},
|
||||||
|
slice(start, end) {
|
||||||
|
return wrap(slice(value, start, end));
|
||||||
|
},
|
||||||
|
map(transform) {
|
||||||
|
return wrap(map(value, transform));
|
||||||
|
},
|
||||||
|
mapNotNull(transform) {
|
||||||
|
return wrap(mapNotNull(value, transform));
|
||||||
|
},
|
||||||
|
flatten<R>() {
|
||||||
|
return wrap(flatten(value as R[][]));
|
||||||
|
},
|
||||||
|
flatMap(transform) {
|
||||||
|
return wrap(flatMap(value, transform));
|
||||||
|
},
|
||||||
|
groupBy(transform) {
|
||||||
|
return wrap(groupBy(value, transform));
|
||||||
|
},
|
||||||
|
associate(transform) {
|
||||||
|
return wrap(associate(value, transform));
|
||||||
|
},
|
||||||
|
associateBy(transform) {
|
||||||
|
return wrap(associateBy(value, transform));
|
||||||
|
},
|
||||||
|
associateWith(transform) {
|
||||||
|
return wrap(associateWith(value, transform));
|
||||||
|
},
|
||||||
|
zip(items) {
|
||||||
|
return wrap(zip(value, items));
|
||||||
|
},
|
||||||
|
unzip<A, B>() {
|
||||||
|
return unzip(value as [A, B][]);
|
||||||
|
},
|
||||||
|
windowed(size, step, partial) {
|
||||||
|
return wrap(windowed(value, size, step, partial));
|
||||||
|
},
|
||||||
|
chunked(size) {
|
||||||
|
return wrap(chunked(value, size));
|
||||||
|
},
|
||||||
|
reversed() {
|
||||||
|
return wrap(reversed(value));
|
||||||
|
},
|
||||||
|
sorted() {
|
||||||
|
return wrap(sorted(value as number[]));
|
||||||
|
},
|
||||||
|
sortedWith(compare) {
|
||||||
|
return wrap(sortedWith(value, compare));
|
||||||
|
},
|
||||||
|
sortedBy(transform) {
|
||||||
|
return wrap(sortedBy(value, transform));
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
6
src/collection/all.ts
Normal file
6
src/collection/all.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
export function all<T>(value: T[], predicate: (it: T) => boolean): boolean {
|
||||||
|
for (const it of value) {
|
||||||
|
if (!predicate(it)) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
6
src/collection/any.ts
Normal file
6
src/collection/any.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
export function any<T>(value: T[], predicate: (it: T) => boolean): boolean {
|
||||||
|
for (const it of value) {
|
||||||
|
if (predicate(it)) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
7
src/collection/associate.ts
Normal file
7
src/collection/associate.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
export function associate<T, K, V>(value: T[], transform: (it: T) => [K, V]): [K, V][] {
|
||||||
|
const result: [K, V][] = [];
|
||||||
|
for (const it of value) {
|
||||||
|
result.push(transform(it));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
7
src/collection/associateBy.ts
Normal file
7
src/collection/associateBy.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
export function associateBy<T, K>(value: T[], transform: (it: T) => K): [K, T][] {
|
||||||
|
const result: [K, T][] = [];
|
||||||
|
for (const it of value) {
|
||||||
|
result.push([transform(it), it]);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
7
src/collection/associateWith.ts
Normal file
7
src/collection/associateWith.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
export function associateWith<T, V>(value: T[], transform: (it: T) => V): [T, V][] {
|
||||||
|
const result: [T, V][] = [];
|
||||||
|
for (const it of value) {
|
||||||
|
result.push([it, transform(it)]);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
10
src/collection/average.ts
Normal file
10
src/collection/average.ts
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import {error} from "../util/error";
|
||||||
|
|
||||||
|
export function average(value: number[]): number {
|
||||||
|
if (value.length === 0) error();
|
||||||
|
let sum = 0;
|
||||||
|
for (const it of value) {
|
||||||
|
sum += it;
|
||||||
|
}
|
||||||
|
return sum / value.length;
|
||||||
|
}
|
||||||
10
src/collection/averageBy.ts
Normal file
10
src/collection/averageBy.ts
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import {error} from "../util/error";
|
||||||
|
|
||||||
|
export function averageBy<T>(value: T[], transform: (it: T) => number): number {
|
||||||
|
if (value.length === 0) error();
|
||||||
|
let sum = 0;
|
||||||
|
for (const it of value) {
|
||||||
|
sum += transform(it);
|
||||||
|
}
|
||||||
|
return sum / value.length;
|
||||||
|
}
|
||||||
8
src/collection/averageByOrNull.ts
Normal file
8
src/collection/averageByOrNull.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
export function averageByOrNull<T>(value: T[], transform: (it: T) => number): number | null {
|
||||||
|
if (value.length === 0) return null;
|
||||||
|
let sum = 0;
|
||||||
|
for (const it of value) {
|
||||||
|
sum += transform(it);
|
||||||
|
}
|
||||||
|
return sum / value.length;
|
||||||
|
}
|
||||||
8
src/collection/averageOrNull.ts
Normal file
8
src/collection/averageOrNull.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
export function averageOrNull(value: number[]): number | null {
|
||||||
|
if (value.length === 0) return null;
|
||||||
|
let sum = 0;
|
||||||
|
for (const it of value) {
|
||||||
|
sum += it;
|
||||||
|
}
|
||||||
|
return sum / value.length;
|
||||||
|
}
|
||||||
16
src/collection/chunked.ts
Normal file
16
src/collection/chunked.ts
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import {error} from "../util/error";
|
||||||
|
|
||||||
|
export function chunked<T>(value: T[], size: number): T[][] {
|
||||||
|
if (size < 1) error();
|
||||||
|
const result: T[][] = [];
|
||||||
|
let buffer: T[] = [];
|
||||||
|
for (const it of value) {
|
||||||
|
buffer.push(it);
|
||||||
|
if (buffer.length === size) {
|
||||||
|
result.push(buffer);
|
||||||
|
buffer = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (buffer.length !== 0) result.push(buffer);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
6
src/collection/contains.ts
Normal file
6
src/collection/contains.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
export function contains<T>(value: T[], item: T): boolean {
|
||||||
|
for (const it of value) {
|
||||||
|
if (it === item) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
7
src/collection/containsAll.ts
Normal file
7
src/collection/containsAll.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
export function containsAll<T>(value: T[], items: Iterable<T>): boolean {
|
||||||
|
const set = new Set(value);
|
||||||
|
for (const it of items) {
|
||||||
|
if (!set.has(it)) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
8
src/collection/count.ts
Normal file
8
src/collection/count.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
export function count<T>(value: T[], predicate?: (it: T) => boolean): number {
|
||||||
|
if (!predicate) return value.length;
|
||||||
|
let count = 0;
|
||||||
|
for (const it of value) {
|
||||||
|
if (predicate(it)) count++;
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
10
src/collection/distinct.ts
Normal file
10
src/collection/distinct.ts
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
export function distinct<T>(value: T[]): T[] {
|
||||||
|
const result: T[] = [];
|
||||||
|
const set: Set<T> = new Set();
|
||||||
|
for (const it of value) {
|
||||||
|
if (set.has(it)) continue;
|
||||||
|
result.push(it);
|
||||||
|
set.add(it);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
11
src/collection/distinctBy.ts
Normal file
11
src/collection/distinctBy.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
export function distinctBy<T, K>(value: T[], transform: (it: T) => K): T[] {
|
||||||
|
const result: T[] = [];
|
||||||
|
const set: Set<K> = new Set();
|
||||||
|
for (const it of value) {
|
||||||
|
const x = transform(it);
|
||||||
|
if (set.has(x)) continue;
|
||||||
|
result.push(it);
|
||||||
|
set.add(x);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
10
src/collection/drop.ts
Normal file
10
src/collection/drop.ts
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import {error} from "../util/error";
|
||||||
|
|
||||||
|
export function drop<T>(value: T[], count: number): T[] {
|
||||||
|
if (count < 0) error();
|
||||||
|
const result: T[] = [];
|
||||||
|
for (let i = count; i < value.length; i++) {
|
||||||
|
result.push(value[i]);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
11
src/collection/dropUntil.ts
Normal file
11
src/collection/dropUntil.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
export function dropUntil<T>(value: T[], predicate: (it: T) => boolean): T[] {
|
||||||
|
let index = 0;
|
||||||
|
while (index < value.length && !predicate(value[index])) {
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
const result: T[] = [];
|
||||||
|
for (let i = index; i < value.length; i++) {
|
||||||
|
result.push(value[i]);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
11
src/collection/dropWhile.ts
Normal file
11
src/collection/dropWhile.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
export function dropWhile<T>(value: T[], predicate: (it: T) => boolean): T[] {
|
||||||
|
let index = 0;
|
||||||
|
while (index < value.length && predicate(value[index])) {
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
const result: T[] = [];
|
||||||
|
for (let i = index; i < value.length; i++) {
|
||||||
|
result.push(value[i]);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
7
src/collection/filter.ts
Normal file
7
src/collection/filter.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
export function filter<T>(value: T[], predicate: (it: T) => boolean): T[] {
|
||||||
|
const result: T[] = [];
|
||||||
|
for (const it of value) {
|
||||||
|
if (predicate(it)) result.push(it);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
10
src/collection/first.ts
Normal file
10
src/collection/first.ts
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import {error} from "../util/error";
|
||||||
|
|
||||||
|
export function first<T>(value: T[], predicate?: (it: T) => boolean): T {
|
||||||
|
if (value.length === 0) error();
|
||||||
|
if (!predicate) return value[0];
|
||||||
|
for (const it of value) {
|
||||||
|
if (predicate(it)) return it;
|
||||||
|
}
|
||||||
|
error();
|
||||||
|
}
|
||||||
8
src/collection/firstOrNull.ts
Normal file
8
src/collection/firstOrNull.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
export function firstOrNull<T>(value: T[], predicate?: (it: T) => boolean): T | null {
|
||||||
|
if (value.length === 0) return null;
|
||||||
|
if (!predicate) return value[0];
|
||||||
|
for (const it of value) {
|
||||||
|
if (predicate(it)) return it;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
7
src/collection/flatMap.ts
Normal file
7
src/collection/flatMap.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
export function flatMap<T, R>(value: T[], transform: (it: T) => Iterable<R>): R[] {
|
||||||
|
const result: R[] = [];
|
||||||
|
for (const it of value) {
|
||||||
|
result.push(...transform(it));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
7
src/collection/flatten.ts
Normal file
7
src/collection/flatten.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
export function flatten<R>(value: R[][]): R[] {
|
||||||
|
const result: R[] = [];
|
||||||
|
for (const it of value) {
|
||||||
|
result.push(...it);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
7
src/collection/fold.ts
Normal file
7
src/collection/fold.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
export function fold<T, R>(value: T[], initial: R, accumulate: (acc: R, it: T) => R): R {
|
||||||
|
let acc = initial;
|
||||||
|
for (const it of value) {
|
||||||
|
acc = accumulate(acc, it);
|
||||||
|
}
|
||||||
|
return acc;
|
||||||
|
}
|
||||||
5
src/collection/forEach.ts
Normal file
5
src/collection/forEach.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
export function forEach<T>(value: T[], action: (it: T) => void) {
|
||||||
|
for (const it of value) {
|
||||||
|
action(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
6
src/collection/get.ts
Normal file
6
src/collection/get.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import {error} from "../util/error";
|
||||||
|
|
||||||
|
export function get<T>(value: T[], index: number): T {
|
||||||
|
if (index < 0 || index >= value.length) error();
|
||||||
|
return value[index];
|
||||||
|
}
|
||||||
4
src/collection/getOrNull.ts
Normal file
4
src/collection/getOrNull.ts
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
export function getOrNull<T>(value: T[], index: number): T | null {
|
||||||
|
if (index < 0 || index >= value.length) return null;
|
||||||
|
return value[index];
|
||||||
|
}
|
||||||
9
src/collection/groupBy.ts
Normal file
9
src/collection/groupBy.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
export function groupBy<T, K>(value: T[], transform: (it: T) => K): [K, T[]][] {
|
||||||
|
const map: Map<K, T[]> = new Map();
|
||||||
|
for (const it of value) {
|
||||||
|
const key = transform(it);
|
||||||
|
if (!map.has(key)) map.set(key, []);
|
||||||
|
map.get(key)!.push(it);
|
||||||
|
}
|
||||||
|
return [...map];
|
||||||
|
}
|
||||||
7
src/collection/indices.ts
Normal file
7
src/collection/indices.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
export function indices<T>(value: T[]): number[] {
|
||||||
|
const result: number[] = [];
|
||||||
|
for (let index = 0; index < value.length; index++) {
|
||||||
|
result.push(index);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
8
src/collection/intersect.ts
Normal file
8
src/collection/intersect.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
export function intersect<T>(value: T[], items: Iterable<T>): T[] {
|
||||||
|
const result: T[] = [];
|
||||||
|
const set = new Set(items);
|
||||||
|
for (const it of value) {
|
||||||
|
if (set.has(it)) result.push(it);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
3
src/collection/isEmpty.ts
Normal file
3
src/collection/isEmpty.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
export function isEmpty<T>(value: T[]): boolean {
|
||||||
|
return value.length === 0;
|
||||||
|
}
|
||||||
3
src/collection/isNotEmpty.ts
Normal file
3
src/collection/isNotEmpty.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
export function isNotEmpty<T>(value: T[]): boolean {
|
||||||
|
return value.length !== 0;
|
||||||
|
}
|
||||||
7
src/collection/joinToString.ts
Normal file
7
src/collection/joinToString.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
export function joinToString<T>(value: T[], separator: string, transform?: (it: T) => string): string {
|
||||||
|
const transformed: string[] = [];
|
||||||
|
for (const it of value) {
|
||||||
|
transformed.push(transform ? transform(it) : String(it));
|
||||||
|
}
|
||||||
|
return transformed.join(separator);
|
||||||
|
}
|
||||||
12
src/collection/last.ts
Normal file
12
src/collection/last.ts
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import {error} from "../util/error";
|
||||||
|
|
||||||
|
export function last<T>(value: T[], predicate?: (it: T) => boolean): T {
|
||||||
|
if (value.length === 0) error();
|
||||||
|
if (!predicate) return value[value.length - 1];
|
||||||
|
let last: T | undefined;
|
||||||
|
for (const it of value) {
|
||||||
|
if (predicate(it)) last = it;
|
||||||
|
}
|
||||||
|
if (last === undefined) error();
|
||||||
|
return last;
|
||||||
|
}
|
||||||
10
src/collection/lastOrNull.ts
Normal file
10
src/collection/lastOrNull.ts
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
export function lastOrNull<T>(value: T[], predicate?: (it: T) => boolean): T | null {
|
||||||
|
if (value.length === 0) return null;
|
||||||
|
if (!predicate) return value[value.length - 1];
|
||||||
|
let last: T | undefined;
|
||||||
|
for (const it of value) {
|
||||||
|
if (predicate(it)) last = it;
|
||||||
|
}
|
||||||
|
if (last === undefined) return null;
|
||||||
|
return last;
|
||||||
|
}
|
||||||
7
src/collection/map.ts
Normal file
7
src/collection/map.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
export function map<T, R>(value: T[], transform: (it: T) => R): R[] {
|
||||||
|
const result: R[] = [];
|
||||||
|
for (const it of value) {
|
||||||
|
result.push(transform(it));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
8
src/collection/mapNotNull.ts
Normal file
8
src/collection/mapNotNull.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
export function mapNotNull<T, R>(value: T[], transform: (it: T) => R | null): R[] {
|
||||||
|
const result: R[] = [];
|
||||||
|
for (const it of value) {
|
||||||
|
const transformed = transform(it);
|
||||||
|
if (transformed !== null) result.push(transformed);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
11
src/collection/max.ts
Normal file
11
src/collection/max.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import {error} from "../util/error";
|
||||||
|
|
||||||
|
export function max(value: number[]): number {
|
||||||
|
if (value.length === 0) error();
|
||||||
|
let max = value[0];
|
||||||
|
for (let index = 1; index < value.length; index++) {
|
||||||
|
const it = value[index];
|
||||||
|
if (it > max) max = it;
|
||||||
|
}
|
||||||
|
return max;
|
||||||
|
}
|
||||||
16
src/collection/maxBy.ts
Normal file
16
src/collection/maxBy.ts
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import {error} from "../util/error";
|
||||||
|
|
||||||
|
export function maxBy<T>(value: T[], transform: (it: T) => number): T {
|
||||||
|
if (value.length === 0) error();
|
||||||
|
let max = value[0];
|
||||||
|
let maxVal = transform(max);
|
||||||
|
for (let index = 1; index < value.length; index++) {
|
||||||
|
const it = value[index];
|
||||||
|
const val = transform(it);
|
||||||
|
if (val > maxVal) {
|
||||||
|
max = it;
|
||||||
|
maxVal = val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return max;
|
||||||
|
}
|
||||||
14
src/collection/maxByOrNull.ts
Normal file
14
src/collection/maxByOrNull.ts
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
export function maxByOrNull<T>(value: T[], transform: (it: T) => number): T | null {
|
||||||
|
if (value.length === 0) return null;
|
||||||
|
let max = value[0];
|
||||||
|
let maxVal = transform(max);
|
||||||
|
for (let index = 1; index < value.length; index++) {
|
||||||
|
const it = value[index];
|
||||||
|
const val = transform(it);
|
||||||
|
if (val > maxVal) {
|
||||||
|
max = it;
|
||||||
|
maxVal = val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return max;
|
||||||
|
}
|
||||||
12
src/collection/maxOf.ts
Normal file
12
src/collection/maxOf.ts
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import {error} from "../util/error";
|
||||||
|
|
||||||
|
export function maxOf<T>(value: T[], transform: (it: T) => number): number {
|
||||||
|
if (value.length === 0) error();
|
||||||
|
let max = transform(value[0]);
|
||||||
|
for (let index = 1; index < value.length; index++) {
|
||||||
|
const it = value[index];
|
||||||
|
const val = transform(it);
|
||||||
|
if (val > max) max = val;
|
||||||
|
}
|
||||||
|
return max;
|
||||||
|
}
|
||||||
10
src/collection/maxOfOrNull.ts
Normal file
10
src/collection/maxOfOrNull.ts
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
export function maxOfOrNull<T>(value: T[], transform: (it: T) => number): number | null {
|
||||||
|
if (value.length === 0) return null;
|
||||||
|
let max = transform(value[0]);
|
||||||
|
for (let index = 1; index < value.length; index++) {
|
||||||
|
const it = value[index];
|
||||||
|
const val = transform(it);
|
||||||
|
if (val > max) max = val;
|
||||||
|
}
|
||||||
|
return max;
|
||||||
|
}
|
||||||
9
src/collection/maxOrNull.ts
Normal file
9
src/collection/maxOrNull.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
export function maxOrNull(value: number[]): number | null {
|
||||||
|
if (value.length === 0) return null;
|
||||||
|
let max = value[0];
|
||||||
|
for (let index = 1; index < value.length; index++) {
|
||||||
|
const it = value[index];
|
||||||
|
if (it > max) max = it;
|
||||||
|
}
|
||||||
|
return max;
|
||||||
|
}
|
||||||
11
src/collection/maxWith.ts
Normal file
11
src/collection/maxWith.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import {error} from "../util/error";
|
||||||
|
|
||||||
|
export function maxWith<T>(value: T[], compare: (a: T, b: T) => number): T {
|
||||||
|
if (value.length === 0) error();
|
||||||
|
let max = value[0];
|
||||||
|
for (let index = 1; index < value.length; index++) {
|
||||||
|
const it = value[index];
|
||||||
|
if (compare(it, max) > 0) max = it;
|
||||||
|
}
|
||||||
|
return max;
|
||||||
|
}
|
||||||
9
src/collection/maxWithOrNull.ts
Normal file
9
src/collection/maxWithOrNull.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
export function maxWithOrNull<T>(value: T[], compare: (a: T, b: T) => number): T | null {
|
||||||
|
if (value.length === 0) return null;
|
||||||
|
let max = value[0];
|
||||||
|
for (let index = 1; index < value.length; index++) {
|
||||||
|
const it = value[index];
|
||||||
|
if (compare(it, max) > 0) max = it;
|
||||||
|
}
|
||||||
|
return max;
|
||||||
|
}
|
||||||
11
src/collection/min.ts
Normal file
11
src/collection/min.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import {error} from "../util/error";
|
||||||
|
|
||||||
|
export function min(value: number[]): number {
|
||||||
|
if (value.length === 0) error();
|
||||||
|
let min = value[0];
|
||||||
|
for (let index = 1; index < value.length; index++) {
|
||||||
|
const it = value[index];
|
||||||
|
if (it < min) min = it;
|
||||||
|
}
|
||||||
|
return min;
|
||||||
|
}
|
||||||
16
src/collection/minBy.ts
Normal file
16
src/collection/minBy.ts
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import {error} from "../util/error";
|
||||||
|
|
||||||
|
export function minBy<T>(value: T[], transform: (it: T) => number): T {
|
||||||
|
if (value.length === 0) error();
|
||||||
|
let min = value[0];
|
||||||
|
let minVal = transform(min);
|
||||||
|
for (let index = 1; index < value.length; index++) {
|
||||||
|
const it = value[index];
|
||||||
|
const val = transform(it);
|
||||||
|
if (val < minVal) {
|
||||||
|
min = it;
|
||||||
|
minVal = val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return min;
|
||||||
|
}
|
||||||
14
src/collection/minByOrNull.ts
Normal file
14
src/collection/minByOrNull.ts
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
export function minByOrNull<T>(value: T[], transform: (it: T) => number): T | null {
|
||||||
|
if (value.length === 0) return null;
|
||||||
|
let min = value[0];
|
||||||
|
let minVal = transform(min);
|
||||||
|
for (let index = 1; index < value.length; index++) {
|
||||||
|
const it = value[index];
|
||||||
|
const val = transform(it);
|
||||||
|
if (val < minVal) {
|
||||||
|
min = it;
|
||||||
|
minVal = val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return min;
|
||||||
|
}
|
||||||
12
src/collection/minOf.ts
Normal file
12
src/collection/minOf.ts
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import {error} from "../util/error";
|
||||||
|
|
||||||
|
export function minOf<T>(value: T[], transform: (it: T) => number): number {
|
||||||
|
if (value.length === 0) error();
|
||||||
|
let min = transform(value[0]);
|
||||||
|
for (let index = 1; index < value.length; index++) {
|
||||||
|
const it = value[index];
|
||||||
|
const val = transform(it);
|
||||||
|
if (val < min) min = val;
|
||||||
|
}
|
||||||
|
return min;
|
||||||
|
}
|
||||||
10
src/collection/minOfOrNull.ts
Normal file
10
src/collection/minOfOrNull.ts
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
export function minOfOrNull<T>(value: T[], transform: (it: T) => number): number | null {
|
||||||
|
if (value.length === 0) return null;
|
||||||
|
let min = transform(value[0]);
|
||||||
|
for (let index = 1; index < value.length; index++) {
|
||||||
|
const it = value[index];
|
||||||
|
const val = transform(it);
|
||||||
|
if (val < min) min = val;
|
||||||
|
}
|
||||||
|
return min;
|
||||||
|
}
|
||||||
9
src/collection/minOrNull.ts
Normal file
9
src/collection/minOrNull.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
export function minOrNull(value: number[]): number | null {
|
||||||
|
if (value.length === 0) return null;
|
||||||
|
let min = value[0];
|
||||||
|
for (let index = 1; index < value.length; index++) {
|
||||||
|
const it = value[index];
|
||||||
|
if (it < min) min = it;
|
||||||
|
}
|
||||||
|
return min;
|
||||||
|
}
|
||||||
11
src/collection/minWith.ts
Normal file
11
src/collection/minWith.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import {error} from "../util/error";
|
||||||
|
|
||||||
|
export function minWith<T>(value: T[], compare: (a: T, b: T) => number): T {
|
||||||
|
if (value.length === 0) error();
|
||||||
|
let min = value[0];
|
||||||
|
for (let index = 1; index < value.length; index++) {
|
||||||
|
const it = value[index];
|
||||||
|
if (compare(it, min) < 0) min = it;
|
||||||
|
}
|
||||||
|
return min;
|
||||||
|
}
|
||||||
9
src/collection/minWithOrNull.ts
Normal file
9
src/collection/minWithOrNull.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
export function minWithOrNull<T>(value: T[], compare: (a: T, b: T) => number): T | null {
|
||||||
|
if (value.length === 0) return null;
|
||||||
|
let min = value[0];
|
||||||
|
for (let index = 1; index < value.length; index++) {
|
||||||
|
const it = value[index];
|
||||||
|
if (compare(it, min) < 0) min = it;
|
||||||
|
}
|
||||||
|
return min;
|
||||||
|
}
|
||||||
8
src/collection/minus.ts
Normal file
8
src/collection/minus.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
export function minus<T>(value: T[], items: Iterable<T>): T[] {
|
||||||
|
const result: T[] = [];
|
||||||
|
const set = new Set(items);
|
||||||
|
for (const it of value) {
|
||||||
|
if (!set.has(it)) result.push(it);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
6
src/collection/none.ts
Normal file
6
src/collection/none.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
export function none<T>(value: T[], predicate: (it: T) => boolean): boolean {
|
||||||
|
for (const it of value) {
|
||||||
|
if (predicate(it)) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
6
src/collection/onEach.ts
Normal file
6
src/collection/onEach.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
export function onEach<T>(value: T[], action: (it: T) => void): T[] {
|
||||||
|
for (const it of value) {
|
||||||
|
action(it);
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
9
src/collection/partition.ts
Normal file
9
src/collection/partition.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
export function partition<T>(value: T[], predicate: (it: T) => boolean): [T[], T[]] {
|
||||||
|
const t: T[] = [];
|
||||||
|
const f: T[] = [];
|
||||||
|
for (const it of value) {
|
||||||
|
if (predicate(it)) t.push(it);
|
||||||
|
else f.push(it);
|
||||||
|
}
|
||||||
|
return [t, f];
|
||||||
|
}
|
||||||
10
src/collection/plus.ts
Normal file
10
src/collection/plus.ts
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
export function plus<T>(value: T[], items: Iterable<T>): T[] {
|
||||||
|
const result: T[] = [];
|
||||||
|
for (const it of value) {
|
||||||
|
result.push(it);
|
||||||
|
}
|
||||||
|
for (const it of items) {
|
||||||
|
result.push(it);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
10
src/collection/reduce.ts
Normal file
10
src/collection/reduce.ts
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import {error} from "../util/error";
|
||||||
|
|
||||||
|
export function reduce<T>(value: T[], accumulate: (acc: T, it: T) => T): T {
|
||||||
|
if (value.length === 0) error();
|
||||||
|
let acc = value[0];
|
||||||
|
for (let index = 1; index < value.length; index++) {
|
||||||
|
acc = accumulate(acc, value[index]);
|
||||||
|
}
|
||||||
|
return acc;
|
||||||
|
}
|
||||||
8
src/collection/reduceOrNull.ts
Normal file
8
src/collection/reduceOrNull.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
export function reduceOrNull<T>(value: T[], accumulate: (acc: T, it: T) => T): T | null {
|
||||||
|
if (value.length === 0) return null;
|
||||||
|
let acc = value[0];
|
||||||
|
for (let index = 1; index < value.length; index++) {
|
||||||
|
acc = accumulate(acc, value[index]);
|
||||||
|
}
|
||||||
|
return acc;
|
||||||
|
}
|
||||||
3
src/collection/reversed.ts
Normal file
3
src/collection/reversed.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
export function reversed<T>(value: T[]): T[] {
|
||||||
|
return [...value].reverse();
|
||||||
|
}
|
||||||
9
src/collection/scan.ts
Normal file
9
src/collection/scan.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
export function scan<T, R>(value: T[], initial: R, accumulate: (acc: R, it: T) => R): R[] {
|
||||||
|
const result: R[] = [initial];
|
||||||
|
let acc = initial;
|
||||||
|
for (const it of value) {
|
||||||
|
acc = accumulate(acc, it);
|
||||||
|
result.push(acc);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
18
src/collection/single.ts
Normal file
18
src/collection/single.ts
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import {error} from "../util/error";
|
||||||
|
|
||||||
|
export function single<T>(value: T[], predicate?: (it: T) => boolean): T {
|
||||||
|
if (value.length === 0) error();
|
||||||
|
if (!predicate) {
|
||||||
|
if (value.length !== 1) error();
|
||||||
|
return value[0];
|
||||||
|
}
|
||||||
|
let last: T | undefined;
|
||||||
|
for (const it of value) {
|
||||||
|
if (predicate(it)) {
|
||||||
|
if (last !== undefined) error();
|
||||||
|
last = it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (last === undefined) error();
|
||||||
|
return last;
|
||||||
|
}
|
||||||
16
src/collection/singleOrNull.ts
Normal file
16
src/collection/singleOrNull.ts
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
export function singleOrNull<T>(value: T[], predicate?: (it: T) => boolean): T | null {
|
||||||
|
if (value.length === 0) return null;
|
||||||
|
if (!predicate) {
|
||||||
|
if (value.length !== 1) return null;
|
||||||
|
return value[0];
|
||||||
|
}
|
||||||
|
let last: T | undefined;
|
||||||
|
for (const it of value) {
|
||||||
|
if (predicate(it)) {
|
||||||
|
if (last !== undefined) return null;
|
||||||
|
last = it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (last === undefined) return null;
|
||||||
|
return last;
|
||||||
|
}
|
||||||
15
src/collection/slice.ts
Normal file
15
src/collection/slice.ts
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import {error} from "../util/error";
|
||||||
|
|
||||||
|
export function slice<T>(value: T[], start: number, end?: number): T[] {
|
||||||
|
if (start < 0) error();
|
||||||
|
if (end !== undefined) {
|
||||||
|
if (end < 0 || end > value.length) error();
|
||||||
|
if (start > end) error();
|
||||||
|
}
|
||||||
|
const result: T[] = [];
|
||||||
|
const limit = end ?? value.length;
|
||||||
|
for (let index = start; index < limit; index++) {
|
||||||
|
result.push(value[index]);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
3
src/collection/sorted.ts
Normal file
3
src/collection/sorted.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
export function sorted(value: number[]): number[] {
|
||||||
|
return [...value].sort((a, b) => a - b);
|
||||||
|
}
|
||||||
3
src/collection/sortedBy.ts
Normal file
3
src/collection/sortedBy.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
export function sortedBy<T>(value: T[], transform: (it: T) => number): T[] {
|
||||||
|
return [...value].sort((a, b) => transform(a) - transform(b));
|
||||||
|
}
|
||||||
3
src/collection/sortedWith.ts
Normal file
3
src/collection/sortedWith.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
export function sortedWith<T>(value: T[], compare: (a: T, b: T) => number): T[] {
|
||||||
|
return [...value].sort(compare);
|
||||||
|
}
|
||||||
7
src/collection/sum.ts
Normal file
7
src/collection/sum.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
export function sum(value: number[]): number {
|
||||||
|
let sum = 0;
|
||||||
|
for (const it of value) {
|
||||||
|
sum += it;
|
||||||
|
}
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
7
src/collection/sumBy.ts
Normal file
7
src/collection/sumBy.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
export function sumBy<T>(value: T[], transform: (it: T) => number): number {
|
||||||
|
let sum = 0;
|
||||||
|
for (const it of value) {
|
||||||
|
sum += transform(it);
|
||||||
|
}
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
11
src/collection/take.ts
Normal file
11
src/collection/take.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import {error} from "../util/error";
|
||||||
|
|
||||||
|
export function take<T>(value: T[], count: number): T[] {
|
||||||
|
if (count < 0) error();
|
||||||
|
const result: T[] = [];
|
||||||
|
const limit = Math.min(count, value.length);
|
||||||
|
for (let index = 0; index < limit; index++) {
|
||||||
|
result.push(value[index]);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
8
src/collection/takeUntil.ts
Normal file
8
src/collection/takeUntil.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
export function takeUntil<T>(value: T[], predicate: (it: T) => boolean): T[] {
|
||||||
|
const result: T[] = [];
|
||||||
|
for (const it of value) {
|
||||||
|
if (predicate(it)) break;
|
||||||
|
result.push(it);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
8
src/collection/takeWhile.ts
Normal file
8
src/collection/takeWhile.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
export function takeWhile<T>(value: Iterable<T>, predicate: (it: T) => boolean): T[] {
|
||||||
|
const result: T[] = [];
|
||||||
|
for (const it of value) {
|
||||||
|
if (!predicate(it)) break;
|
||||||
|
result.push(it);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
3
src/collection/toArray.ts
Normal file
3
src/collection/toArray.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
export function toArray<T>(value: T[]): T[] {
|
||||||
|
return [...value];
|
||||||
|
}
|
||||||
3
src/collection/toMap.ts
Normal file
3
src/collection/toMap.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
export function toMap<K, V>(value: [K, V][]): Map<K, V> {
|
||||||
|
return new Map(value);
|
||||||
|
}
|
||||||
3
src/collection/toSet.ts
Normal file
3
src/collection/toSet.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
export function toSet<T>(value: T[]): Set<T> {
|
||||||
|
return new Set(value);
|
||||||
|
}
|
||||||
9
src/collection/unzip.ts
Normal file
9
src/collection/unzip.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
export function unzip<A, B>(value: [A, B][]): [A[], B[]] {
|
||||||
|
const resultA: A[] = [];
|
||||||
|
const resultB: B[] = [];
|
||||||
|
for (const [a, b] of value) {
|
||||||
|
resultA.push(a);
|
||||||
|
resultB.push(b);
|
||||||
|
}
|
||||||
|
return [resultA, resultB];
|
||||||
|
}
|
||||||
22
src/collection/windowed.ts
Normal file
22
src/collection/windowed.ts
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import {error} from "../util/error";
|
||||||
|
|
||||||
|
export function windowed<T>(value: T[], size: number, step: number = 1, partial: boolean = false): T[][] {
|
||||||
|
if (size < 1) error();
|
||||||
|
if (step < 1) error();
|
||||||
|
const result: T[][] = [];
|
||||||
|
const buffer: T[] = [];
|
||||||
|
for (const it of value) {
|
||||||
|
buffer.push(it);
|
||||||
|
if (buffer.length === size) {
|
||||||
|
result.push([...buffer]);
|
||||||
|
buffer.splice(0, step);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (partial) {
|
||||||
|
while (buffer.length !== 0) {
|
||||||
|
result.push([...buffer]);
|
||||||
|
buffer.splice(0, step);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
7
src/collection/withIndex.ts
Normal file
7
src/collection/withIndex.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
export function withIndex<T>(value: T[]): [number, T][] {
|
||||||
|
const result: [number, T][] = [];
|
||||||
|
for (let index = 0; index < value.length; index++) {
|
||||||
|
result.push([index, value[index]]);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
13
src/collection/zip.ts
Normal file
13
src/collection/zip.ts
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
export function zip<T, B>(value: T[], items: Iterable<B>): [T, B][] {
|
||||||
|
const result: [T, B][] = [];
|
||||||
|
const iteratorA = value[Symbol.iterator]();
|
||||||
|
const iteratorB = items[Symbol.iterator]();
|
||||||
|
let a = iteratorA.next();
|
||||||
|
let b = iteratorB.next();
|
||||||
|
while (!a.done && !b.done) {
|
||||||
|
result.push([a.value, b.value]);
|
||||||
|
a = iteratorA.next();
|
||||||
|
b = iteratorB.next();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
export {type Collection, collection} from "./collection";
|
||||||
|
|||||||
3
src/util/error.ts
Normal file
3
src/util/error.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
export function error(message?: string): never {
|
||||||
|
throw Error(message);
|
||||||
|
}
|
||||||
@@ -1,11 +1,10 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"moduleResolution": "NodeNext",
|
|
||||||
"module": "NodeNext",
|
|
||||||
"target": "ESNext",
|
|
||||||
"rootDir": "./src/",
|
"rootDir": "./src/",
|
||||||
|
"target": "ESNext",
|
||||||
|
"module": "ESNext",
|
||||||
|
"moduleResolution": "bundler",
|
||||||
"outDir": "./dist/",
|
"outDir": "./dist/",
|
||||||
"declaration": true,
|
"declaration": true
|
||||||
"strict": true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user