// zip two arrays export function zip(a, b) { return a.map((k, i) => [k, b[i]]); } export function capitalizeFirstLetter(val) { return String(val).charAt(0).toUpperCase() + String(val).slice(1); } const _mapRecursiveStructure = mapping => transform => root => { const found = mapping.get(root); if (found) { // already mapped // return existing result to prevent endless recursion return found; } // note the indirection (wrapped in lamda), this allows the user to recursively map the children (which may refer to the root) without yet having finished mapping the root. let memo; const result = () => { // memoization is necessary for correctness return memo || (memo = transform(root, _mapRecursiveStructure(mapping)(transform))); }; mapping.set(root, result); return result; }; export const mapRecursiveStructure = _mapRecursiveStructure(new Map()); export const memoize = callback => { let called = false let result; return () => { if (!called) { result = callback(); called = true; } return result; }; };