zifferjs
Version:
Zifferjs - Typescript variant of Ziffers
77 lines (67 loc) • 2.18 kB
text/typescript
export const seededRandom = (seed: string = ''): (() => number) => {
let x: number = 0;
let y: number = 0;
let z: number = 0;
let w: number = 0;
function next(): number {
const t: number = (x ^ (x << 11)) >>> 0;
x = y;
y = z;
z = w;
w ^= ((w >>> 19) ^ t ^ (t >>> 8)) >>> 0
return (w >>> 0) / 0x100000000;
}
for (let k = 0; k < seed.length + 64; k++) {
x ^= seed.charCodeAt(k) | 0;
next();
}
return next;
}
export const deepClone = <T, U = T extends Array<infer V> ? V : never>(source: T ): T => {
if (Array.isArray(source)) {
return source.map(item => (deepClone(item))) as T & U[]
}
if (source && typeof source === 'object') {
return (Object.getOwnPropertyNames(source) as (keyof T)[]).reduce<T>((o, prop) => {
Object.defineProperty(o, prop, Object.getOwnPropertyDescriptor(source, prop)!)
o[prop] = deepClone(source[prop])
return o
}, Object.create(Object.getPrototypeOf(source)))
}
return source
}
export const choose = <T>(arr: Array<T>): T => {
return arr[Math.floor(Math.random() * arr.length)];
}
export const safeEval = (expression: string): number => {
try {
return new Function(`"use strict";return (${expression})`)();
} catch (error) {
throw new Error(`Error in eval: ${error}`);
}
}
export const safeMod = (value: number, n: number) => {
if(value === 0 || n === 0) return 0;
return ((value % n) + n) % n;
}
export function filterObject(
obj: Record<string, any>|undefined,
filter: string[],
rename: Record<string, string> = {},
): Record<string, any> {
/*
* Filter certain keys from object
*
* @param {Record<string, any>} obj - Object to filter
* @param {string[]} filter - Keys to filter
* @returns {object} Filtered object
*
*/
if(obj === undefined) return {};
return Object.fromEntries(
Object.entries(obj).filter(([key]) => filter.includes(key)).map(([key, value]) => [rename[key] || key, value])
);
}
export const repeat = (value: any, n: number): any[] => {
return Array(n).fill(value).flat();
}