Last active
November 4, 2023 13:08
-
-
Save JonathonAshworth/330d288364525d947efc8f8dc5bf7472 to your computer and use it in GitHub Desktop.
Collection of JS Utility Functions
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // f of the form v => v | |
| export const objMap = (obj, f) => | |
| Object.fromEntries(Object.entries(obj).map(([k, v]) => [k, f(v)])); | |
| // f of the form ([k, v]) => [k, v] | |
| export const objMapEntries = (obj, f) => | |
| Object.fromEntries(Object.entries(obj).map(f)); | |
| export const arrDeepMap = (arr, f) => arr.map((x, i, a) => Array.isArray(x) ? arrDeepMap(x, f) : f(x, i, a)); | |
| export const arrZip = (a, b) => a.map((ax, ai) => [ax, b[ai]]); | |
| // Immutable deep set on both objects and arrays | |
| export const imSet = (objOrArray, path, valueOrFunc) => { | |
| const multipath = Array.isArray(path) && path.length > 1; | |
| const pathItem = Array.isArray(path) ? path[0] : path; // unwrap single item array | |
| const isFunc = typeof valueOrFunc === "function"; | |
| const value = multipath | |
| ? imSet(objOrArray[pathItem], path.slice(1), valueOrFunc) | |
| : isFunc ? valueOrFunc(objOrArray[pathItem]) : valueOrFunc; | |
| if (Array.isArray(objOrArray)) { | |
| return [ | |
| ...objOrArray.slice(0, pathItem), | |
| value, | |
| ...objOrArray.slice(pathItem + 1), | |
| ]; | |
| } else { | |
| return { | |
| ...objOrArray, | |
| [pathItem]: value, | |
| }; | |
| } | |
| }; | |
| // short array accessors | |
| export const aLast = a => a[a.length - 1]; | |
| export const aPrev = (a, i) => i === 0 ? a[a.length - 1] : a[i - 1]; // looping previous | |
| export const aNext = (a, i) => i === a.length - 1 ? a[0] : a[i + 1]; // looping next | |
| export const aFront = a => a.slice(0, a.length / 2); // first half | |
| export const aBack = a => a.slice(a.length / 2); // second half | |
| export const aReverse = a => a.slice().reverse(); // immutable reverse | |
| export const singleton = constructor => (...args) => { | |
| let instance = null; | |
| if (instance) return instance; | |
| instance = constructor(...args); | |
| return instance; | |
| } | |
| export const pipe = (x, ...fs) => fs.reduce((_, f) => f(_), x); | |
| const isObj = o => typeof o === 'object' && o !== null && !Array.isArray(o); | |
| // deeply converts from lower snake case (DB) to camel case (JS front end) | |
| // probably brittle, only use on simple data structures | |
| const strCamel = s => s.replace(/([-_][a-z])/g, g => g.slice(-1).toUpperCase()); | |
| export const objDeepCamel = obj => | |
| objMapEntries(obj, ([k, v]) => [strCamel(k), isObj(v) ? objDeepCamel(v) : v]); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment