From d052f2eee520986ee81e0b97aeb18c8fede07970 Mon Sep 17 00:00:00 2001 From: Alec Larson <1925840+aleclarson@users.noreply.github.com> Date: Tue, 2 Jul 2024 14:59:27 -0400 Subject: [PATCH] chore: format --- ...rt-iterables-in-some-array-functions.patch | 239 ++++++++++++++++++ src/array/replaceOrAppend.ts | 2 +- 2 files changed, 240 insertions(+), 1 deletion(-) create mode 100644 0001-feat-array-support-iterables-in-some-array-functions.patch diff --git a/0001-feat-array-support-iterables-in-some-array-functions.patch b/0001-feat-array-support-iterables-in-some-array-functions.patch new file mode 100644 index 00000000..8f9ceb51 --- /dev/null +++ b/0001-feat-array-support-iterables-in-some-array-functions.patch @@ -0,0 +1,239 @@ +From 87c38ee9537a269cc3f8fe4da7990291f9edad0e Mon Sep 17 00:00:00 2001 +From: Alec Larson <1925840+aleclarson@users.noreply.github.com> +Date: Sat, 22 Jun 2024 14:34:09 -0400 +Subject: [PATCH] feat(array): support iterables in some array functions + +--- + src/array.ts | 115 +++++++++++++++++++++++++++++++++++---------------- + 1 file changed, 80 insertions(+), 35 deletions(-) + +diff --git a/src/array.ts b/src/array.ts +index c7e70d4..f7e9cd9 100644 +--- a/src/array.ts ++++ b/src/array.ts +@@ -6,10 +6,10 @@ import { isArray, isFunction } from './typed' + * each item in that group. + */ + export const group = ( +- array: readonly T[], ++ array: Iterable, + getGroupId: (item: T) => Key + ): Partial> => { +- return array.reduce((acc, item) => { ++ return reduce(array, (acc, item) => { + const groupId = getGroupId(item) + if (!acc[groupId]) acc[groupId] = [] + acc[groupId].push(item) +@@ -58,10 +58,10 @@ export function zip(...arrays: T[][]): T[][] { + * Ex. const zipped = zipToObject(['a', 'b'], 1) // { a: 1, b: 1 } + */ + export function zipToObject( +- keys: K[], ++ keys: Iterable, + values: V | ((key: K, idx: number) => V) | V[] + ): Record { +- if (!keys.length) { ++ if (isEmpty(keys)) { + return {} as Record + } + +@@ -71,7 +71,7 @@ export function zipToObject( + ? (_k: K, i: number) => values[i] + : (_k: K, _i: number) => values + +- return keys.reduce((acc, key, idx) => { ++ return reduce(keys, (acc, key, idx) => { + acc[key] = getValue(key, idx) + return acc + }, {} as Record) +@@ -82,30 +82,37 @@ export function zipToObject( + * and comparing with the second. Keep the one you want then + * compare that to the next item in the list with the same + * +- * Ex. const greatest = () => boil(numbers, (a, b) => a > b) ++ * Ex. const greatest = () => boil(numbers, (a, b) => a > b ? a : b) + */ +-export const boil = ( +- array: readonly T[], ++export function boil(array: readonly [T, ...T[]], compareFunc: (a: T, b: T) => T): T ++export function boil(array: Iterable, compareFunc: (a: T, b: T) => T): T | null ++export function boil ( ++ array: Iterable, + compareFunc: (a: T, b: T) => T +-) => { +- if (!array || (array.length ?? 0) === 0) return null +- return array.reduce(compareFunc) ++) { ++ if (isEmpty(array)) return null ++ let acc!: T, i = 0 ++ for (const item of array) { ++ acc = i++ === 0 ? item : compareFunc(acc, item) ++ } ++ return acc + } + + /** + * Sum all numbers in an array. Optionally provide a function + * to convert objects in the array to number values. + */ +-export function sum(array: readonly T[]): number +-export function sum( +- array: readonly T[], +- fn: (item: T) => number ++export function sum(array: Iterable): number ++export function sum( ++ array: Iterable, ++ getter: (item: T) => number + ): number +-export function sum( +- array: readonly any[], +- fn?: (item: T) => number ++export function sum( ++ array: Iterable, ++ getter?: (item: T) => number + ): number { +- return (array || []).reduce((acc, item) => acc + (fn ? fn(item) : item), 0) ++ const get = getter ?? ((v: any) => v) ++ return reduce(array, (acc, item) => acc + get(item), 0) + } + + /** +@@ -160,10 +167,10 @@ export const alphabetical = ( + } + + export const counting = ( +- list: readonly T[], ++ list: Iterable, + identity: (item: T) => TId + ): Record => { +- return list.reduce((acc, item) => { ++ return reduce(list, (acc, item) => { + const id = identity(item) + acc[id] = (acc[id] ?? 0) + 1 + return acc +@@ -198,11 +205,11 @@ export const replace = ( + * into a dictionary key & value + */ + export const objectify = ( +- array: readonly T[], ++ array: Iterable, + getKey: (item: T) => Key, + getValue: (item: T) => Value = item => item as unknown as Value + ): Record => { +- return array.reduce((acc, item) => { ++ return reduce(array, (acc, item) => { + acc[getKey(item)] = getValue(item) + return acc + }, {} as Record) +@@ -216,11 +223,11 @@ export const objectify = ( + * select([1, 2, 3, 4], x => x*x, x > 2) == [9, 16] + */ + export const select = ( +- array: readonly T[], ++ array: Iterable, + mapper: (item: T, index: number) => K, + condition: (item: T, index: number) => boolean + ) => { +- return array.reduce((acc, item, index) => { ++ return reduce(array, (acc, item, index) => { + if (!condition(item, index)) return acc + acc.push(mapper(item, index)) + return acc +@@ -235,15 +242,19 @@ export const select = ( + * max([{ num: 1 }, { num: 2 }], x => x.num) == { num: 2 } + */ + export function max(array: readonly [number, ...number[]]): number +-export function max(array: readonly number[]): number | null ++export function max(array: Iterable): number | null + export function max( +- array: readonly T[], ++ array: readonly [T, ...T[]], ++ getter: (item: T) => number ++): T ++export function max( ++ array: Iterable, + getter: (item: T) => number + ): T | null + export function max( +- array: readonly T[], ++ array: Iterable, + getter?: (item: T) => number +-): T | null { ++) { + const get = getter ?? ((v: any) => v) + return boil(array, (a, b) => (get(a) > get(b) ? a : b)) + } +@@ -256,15 +267,19 @@ export function max( + * min([{ num: 1 }, { num: 2 }], x => x.num) == { num: 1 } + */ + export function min(array: readonly [number, ...number[]]): number +-export function min(array: readonly number[]): number | null ++export function min(array: Iterable): number | null + export function min( +- array: readonly T[], ++ array: readonly [T, ...T[]], ++ getter: (item: T) => number ++): T ++export function min( ++ array: Iterable, + getter: (item: T) => number + ): T | null + export function min( +- array: readonly T[], ++ array: Iterable, + getter?: (item: T) => number +-): T | null { ++) { + const get = getter ?? ((v: any) => v) + return boil(array, (a, b) => (get(a) < get(b) ? a : b)) + } +@@ -288,10 +303,10 @@ export const cluster = (list: readonly T[], size: number = 2): T[][] => { + * value + */ + export const unique = ( +- array: readonly T[], ++ array: Iterable, + toKey?: (item: T) => K + ): T[] => { +- const valueMap = array.reduce((acc, item) => { ++ const valueMap = reduce(array, (acc, item) => { + const key = toKey ? toKey(item) : (item as any as string | number | symbol) + if (acc[key]) return acc + acc[key] = item +@@ -534,3 +549,33 @@ export function shift(arr: Array, n: number) { + + return [...arr.slice(-shiftNumber, arr.length), ...arr.slice(0, -shiftNumber)] + } ++ ++function reduce( ++ iterable: Iterable, ++ reducer: (acc: K | undefined, item: T, index: number) => K, ++): K ++function reduce( ++ iterable: Iterable, ++ reducer: (acc: K, item: T, index: number) => K, ++ initial: K ++): K ++function reduce( ++ iterable: Iterable, ++ reducer: (acc: K | undefined, item: T, index: number) => K, ++ initial?: K, ++) { ++ let acc = initial ++ let index = 0 ++ for (const item of iterable) { ++ acc = reducer(acc, item, index) ++ index++ ++ } ++ return acc ++} ++ ++ ++function isEmpty(iterable: Iterable | readonly any[]) { ++ if (isArray(iterable)) return !iterable.length ++ for (const _ of iterable) return false ++ return true ++} +-- +2.41.0 + diff --git a/src/array/replaceOrAppend.ts b/src/array/replaceOrAppend.ts index e0c0a598..f3a56322 100644 --- a/src/array/replaceOrAppend.ts +++ b/src/array/replaceOrAppend.ts @@ -28,7 +28,7 @@ export function replaceOrAppend( const out = array.slice() for (let index = 0; index < array.length; index++) { if (match(array[index], index)) { - out[index] = newItem; + out[index] = newItem return out } }