Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | 1x 1x 1x 3x 3x 3x 8x 3x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 13x 3x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 15x 4x 4x 15x 15x 15x 15x 15x 15x 3x 3x 2x 2x | export const RecursiveObj = { largeRandom() { return `ref:${Math.floor(Math.random() * 100_000_000_000)}`; }, flatten(a, references = {}, found = []) { if (typeof a !== 'object') { return { obj: a, references, found }; } const keys = Object.keys(a); const newObj = a instanceof Array ? [] : {}; for (let i = 0; i < keys.length; i++) { const key = keys[i]; // Already been cataloged const kvPair = found.find(({ v }) => v === a[key]); if (kvPair) { newObj[key] = kvPair.k; continue; } const r = { k: RecursiveObj.largeRandom() }; const flattened = RecursiveObj.flatten( a[key], references, found.concat({ v: a[key], k: r.k }), ); r.v = flattened.obj; references = { // eslint-disable-line no-param-reassign ...references, ...flattened.references, [r.k]: r.v, }; found = flattened.found; // eslint-disable-line no-param-reassign newObj[key] = flattened.obj; } return { obj: newObj, references, found }; }, inflate(a, references, inflated = {}) { if (typeof a !== 'object') { return a; } const keys = Object.keys(a); const newObj = a instanceof Array ? [] : {}; for (let i = 0; i < keys.length; i++) { const key = keys[i]; const val = a[key]; // Already been inflated if (typeof val === 'string' && inflated[val] != null) { newObj[key] = inflated[val]; continue; } // Uninflated reference if (typeof val === 'string' && references[val] != null) { const flat = { ...references[val] }; inflated[val] = flat; // eslint-disable-line no-param-reassign const filled = RecursiveObj.inflate(flat, references, inflated); // Move the inflated properties over to the "flat" object Object.keys(filled).forEach((t) => { flat[t] = filled[t]; }); newObj[key] = inflated[val]; continue; } // Not a reference newObj[key] = RecursiveObj.inflate(val, references, inflated); } return newObj; }, stringify(a) { const { obj, references } = RecursiveObj.flatten(a); return JSON.stringify({ obj, references }); }, parse(a) { const { obj, references } = JSON.parse(a); return RecursiveObj.inflate(obj, references); }, }; |