import util from "node:util"; export const eq = util.isDeepStrictEqual; export const keys = (ks, obj) => ks.reduce( (ret, k) => obj.hasOwnProperty(k) ? {...ret, [k]: obj[k]} : ret, {}, ); export const difference = (a, b) => { const diff = new Set(a); for (const el of b) { diff.delete(el); } return diff; }; export const assocIn = (obj, path, value) => path.length === 0 ? obj : path.length === 1 ? { ...obj, [path[0]]: value } : { ...obj, [path[0]]: assocIn( (obj[path[0]] || {}), path.slice(1), value ) }; export const dissoc = (obj, key) => { const ret = { ...obj }; delete ret[key] return ret; }; export const getIn = (obj, path) => path.length === 0 ? obj : getIn(obj?.[path[0]], path.slice(1)); export const findFirst = (arr, fn) => { for (const x of arr) { const ret = fn(x); if (ret) { return ret; } } return null; }; export const partial = (fn, ...startArgs) => (...endArgs) => fn(...startArgs, ...endArgs); export const strSortFn = (a, b) => a.localeCompare(b, "POSIX"); export const undefinedAsNull = x => x === undefined ? null : x; export const first = a => a[0]; export const rest = a => a.slice(1); export const butlast = a => a.slice(a, a.length - 1); export const last = a => a[a.length - 1]; export const take = function*(n, gen) { let i = 0n; for (const x of gen) { if (i >= n) { break; } i++; yield x; } }; export const range = function*(x, y, step = 1n) { if (x === undefined) { let i = 0n; while (true) { yield i++; } } const [from, to] = y === undefined ? [0n, x] : [x, y]; const fromn = BigInt(from); const ton = BigInt(to); const stepn = BigInt(step); if (stepn === 0n) { while (true) { yield fromn; } } if (step < 0n) { for (let i = fromn; i > ton; i+= stepn) { yield i; } } else { for (let i = fromn; i < ton; i += stepn) { yield i; } } };