Last active
April 23, 2018 17:08
-
-
Save dmitru/f4168cd32899281b068d953e7f76fe4a to your computer and use it in GitHub Desktop.
Function for deep object flattening (see test cases)
This file contains 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
import map from 'lodash/map' | |
function deepFlattenHelper(obj, acc = {}, path = []) { | |
if (!obj) { | |
return acc | |
} | |
let result = { ...acc } | |
if (typeof obj === 'object') { | |
map(obj, (value, key) => { | |
if (typeof value === 'object') { | |
result = { | |
...result, | |
...deepFlattenHelper(value, acc, path.concat(key)), | |
} | |
} else if (typeof value !== 'undefined') { | |
result[path.concat(key).join('.')] = value | |
} | |
}) | |
} | |
return result | |
} | |
export default function deepFlatten(obj) { | |
if (!obj) { | |
return obj | |
} | |
return deepFlattenHelper(obj) | |
} |
This file contains 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
import deepFlatten from './deepFlatten' | |
describe('utils/deepFlatten', () => { | |
it('Should work for an empty object', async () => { | |
const result = deepFlatten({}) | |
expect(result).toEqual({}) | |
}) | |
it('Should work for a null', async () => { | |
const result = deepFlatten(null) | |
expect(result).toEqual(null) | |
}) | |
it('Should work for an undefined', async () => { | |
const result = deepFlatten(undefined) | |
expect(result).toEqual(undefined) | |
}) | |
it('Should work for a 1-level object', async () => { | |
const result = deepFlatten({ a: 1, b: 2 }) | |
expect(result).toEqual({ a: 1, b: 2 }) | |
}) | |
it('Should work for a 1-level object with array', async () => { | |
const result = deepFlatten({ a: 1, b: 2, c: [3] }) | |
expect(result).toEqual({ a: 1, b: 2, 'c.0': 3 }) | |
}) | |
it('Should deeply filter all undefined values', async () => { | |
const result = deepFlatten([ | |
{ a: undefined, b: { bb: undefined }, c: [undefined, { d: undefined, e: { f: undefined } }] }, | |
]) | |
expect(result).toEqual({}) | |
}) | |
it('Should work for arrays with missing indices', async () => { | |
const array = [] | |
array[1] = 'a' | |
array[2] = 'b' | |
const result = deepFlatten({ a: array }) | |
expect(result).toEqual({ 'a.1': 'a', 'a.2': 'b' }) | |
expect(Object.keys(result)).toEqual(['a.1', 'a.2']) | |
}) | |
it('Should work for a 2-level object with an array', async () => { | |
const result = deepFlatten({ a: { b: 2, c: [3, 4, { d: 5 }] } }) | |
expect(result).toEqual({ 'a.b': 2, 'a.c.0': 3, 'a.c.1': 4, 'a.c.2.d': 5 }) | |
}) | |
it('Should work for a deep complex mixed object with arrays', async () => { | |
const result = deepFlatten({ a: { b: 2, c: [3, 4, { d: 5, e: [{ f: 6 }] }] } }) | |
expect(result).toEqual({ 'a.b': 2, 'a.c.0': 3, 'a.c.1': 4, 'a.c.2.d': 5, 'a.c.2.e.0.f': 6 }) | |
}) | |
it('Should work for an array of objects', async () => { | |
const result = deepFlatten([1, { b: 2 }]) | |
expect(result).toEqual({ '0': 1, '1.b': 2 }) | |
}) | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment