@indigo-labs/indigo-sdk
Version:
Indigo SDK for interacting with Indigo endpoints via lucid-evolution
109 lines (96 loc) • 2.42 kB
text/typescript
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()],
]),
);
};