UNPKG

@indigo-labs/indigo-sdk

Version:

Indigo SDK for interacting with Indigo endpoints via lucid-evolution

109 lines (96 loc) 2.42 kB
import { array as A, ord as Ord, readonlyArray as RA, option as O, function as F, } from 'fp-ts'; import { Predicate } from 'fp-ts/lib/Predicate'; export function shuffle<T>(arr: T[]): T[] { const source = [...arr]; for (let i = source.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [source[i], source[j]] = [source[j], source[i]]; } return source; } /** * The parameter `arr` should be sorted for correct results. */ export function insertSorted<T>(arr: T[], item: T, ord: Ord.Ord<T>): T[] { if (arr.length === 0) { return [item]; } const arrOrd = ord.compare(arr[0], arr[arr.length - 1]); // Array containing the same items if (arrOrd === 0) { if (ord.compare(arr[0], item) === -1) { return [...arr, item]; } else { return [item, ...arr]; } } // TODO: could be improved with binary search for (let i = 0; i < arr.length; i++) { if (ord.compare(arr[i], item) !== arrOrd) { return [...A.takeLeft(i)(arr), item, ...A.takeRight(arr.length - i)(arr)]; } } return [...arr, item]; } /** * Replace when existent, otherwise add at the end. */ export const repsertReadonlyArr = <K, V>(predicate: Predicate<K>, val: V, mkKey: () => K) => (arr: ReadonlyArray<readonly [K, V]>): ReadonlyArray<readonly [K, V]> => { const idx = F.pipe( arr, RA.findIndex(([key, _]) => predicate(key)), ); const res = F.pipe( idx, O.chain((i) => F.pipe( arr, RA.modifyAt(i, ([key, _]) => [key, val]), ), ), ); return F.pipe( res, O.getOrElse<ReadonlyArray<readonly [K, V]>>(() => [ ...arr, [mkKey(), val], ]), ); }; export const repsertWithReadonlyArr = <K, V>( predicate: Predicate<K>, replaceVal: (oldVal: V) => V, newVal: () => V, mkKey: () => K, ) => (arr: ReadonlyArray<readonly [K, V]>): ReadonlyArray<readonly [K, V]> => { const idx = F.pipe( arr, RA.findIndex(([key, _]) => predicate(key)), ); const res = F.pipe( idx, O.chain((i) => F.pipe( arr, RA.modifyAt(i, ([key, oldVal]) => [key, replaceVal(oldVal)]), ), ), ); return F.pipe( res, O.getOrElse<ReadonlyArray<readonly [K, V]>>(() => [ ...arr, [mkKey(), newVal()], ]), ); };