Add whereDefined and mapCall methods to Collection class

This commit is contained in:
Garrett Mills 2022-01-20 00:55:11 -06:00
parent 32050cb2ce
commit cfd555723b
2 changed files with 30 additions and 5 deletions

View File

@ -14,7 +14,7 @@ type MaybeCollectionIndex = CollectionIndex | undefined
type ComparisonFunction<T> = (item: CollectionItem<T>, otherItem: CollectionItem<T>) => number
import { WhereOperator, applyWhere, whereMatch } from './where'
import {Awaitable, Either, isLeft, right, unright} from '../support/types'
import {Awaitable, Either, isLeft, Maybe, MethodsOf, right, unright} from '../support/types'
const collect = <T>(items: CollectionItem<T>[]): Collection<T> => Collection.collect(items)
const toString = (item: unknown): string => String(item)
@ -293,7 +293,7 @@ class Collection<T> {
* Stops executing if a single truth case is found.
* @param func
*/
some(func: (item: T) => boolean): boolean {
some(func: (item: T) => Maybe<boolean>): boolean {
return this.storedItems.some(func)
}
@ -355,6 +355,23 @@ class Collection<T> {
return right(new Collection<TRight>(newItems))
}
/**
* Map a method on the underlying type, passing it any required parameters.
* This is delightfully type-safe.
* @param method
* @param params
*/
mapCall<T2 extends MethodsOf<T>>(method: T2, ...params: Parameters<T[T2]>): Collection<ReturnType<T[T2]>> {
return this.map(x => x[method](...params))
}
/**
* Map each element in the collection to a string.
*/
strings(): Collection<string> {
return this.map<string>(x => String(x))
}
/**
* Create a new collection by mapping the items in this collection using the given function,
* excluding any for which the function returns undefined.
@ -441,8 +458,12 @@ class Collection<T> {
* Return a new collection filtered by the given function.
* @param func
*/
filter<T2>(func: KeyFunction<T, T2>): Collection<T> {
return new Collection(this.storedItems.filter(func))
filter<T2>(func?: KeyFunction<T, T2>): Collection<T> {
return new Collection(this.storedItems.filter(func ?? Boolean))
}
whereDefined(): Collection<NonNullable<T>> {
return this.filter() as unknown as Collection<NonNullable<T>>
}
/**
@ -780,7 +801,7 @@ class Collection<T> {
* Return the max value of the given key.
* @param key
*/
max<T2>(key: KeyOperator<T, T2>): number {
max<T2 = T>(key: KeyOperator<T, T2>): number {
const values = this.allAsNumbers(key)
return Math.max(...values)
}

View File

@ -68,3 +68,7 @@ export interface TypeTag<S extends string> {
export type PrefixTypeArray<T, TArr extends unknown[]> = [T, ...TArr]
export type SuffixTypeArray<TArr extends unknown[], T> = [...TArr, T]
export type TypeArraySignature<TArr extends unknown[], TReturn> = (...params: TArr) => TReturn
export type MethodsOf<T, TMethod = (...args: any[]) => any> = {
[K in keyof T]: T[K] extends TMethod ? K : never
}[keyof T]