Skip to content

Instantly share code, notes, and snippets.

@ymkins
Forked from dominikwilkowski/README.md
Last active February 19, 2018 17:26
Show Gist options
  • Save ymkins/25da3a95118968e035bc32eb2b10d619 to your computer and use it in GitHub Desktop.
Save ymkins/25da3a95118968e035bc32eb2b10d619 to your computer and use it in GitHub Desktop.
Flatten javascript objects into a single-depth object with ES6

Flatten a deep javascript object into single-depth object with ES6

Call it via:

const flat = flatten( realDeepObject ),
      flatDotted = flatten( realDeepObject, '', '.' );

Test case:

const realDeepObject = {
  level1: {
    level2: {
      level3: {
        more: 'stuff', //duplicate key
        other: 'stuff',
        level4: {
          the: 'end',
        },
      },
    },
    level2still: {
      last: 'one',
    },
    am: 'bored',
  },
  more: 'stuff', //duplicate key
  ipsum: {
    lorem: 'latin',
  },
};

const flat = flatten( realDeepObject ),
      flatDotted = flatten( realDeepObject, '', '.' );

console.log( flat, flatDotted );

Output:

{ '/level1/level2/level3/more': 'stuff',
  '/level1/level2/level3/other': 'stuff',
  '/level1/level2/level3/level4/the': 'end',
  '/level1/level2still/last': 'one',
  '/level1/am': 'bored',
  '/more': 'stuff',
  '/ipsum/lorem': 'latin' }

{ 'level1.level2.level3.more': 'stuff',
  'level1.level2.level3.other': 'stuff',
  'level1.level2.level3.level4.the': 'end',
  'level1.level2still.last': 'one',
  'level1.am': 'bored',
  'more': 'stuff',
  'ipsum.lorem': 'latin' }
/**
* PRIVATE
* Flatten a deep object into a one level object with it’s path as key
*
* @param {object} object - The object to be flattened
* @param {string} pathRoot - Starts path with
* @param {string} pathDelim - The path delimeter
* @return {object} - The resulting flat object
*/
const flatten = (object, pathRoot = '/', pathDelim = '/') => {
return Object.assign( {}, ...function _flatten( objectBit, path = '' ) { //spread the result into our return object
if (objectBit === null) { //deal with null
return { [path]: null }
}
path = path.length ? `${path}${pathDelim}` : pathRoot //deal with path
return [].concat( //concat everything into one level
...Object.keys( objectBit ).map( //iterate over object
key => typeof objectBit[ key ] === 'object' ? //check if there is a nested object
_flatten( objectBit[ key ], `${ path }${ key }` ) : //call itself if there is
( { [ `${ path }${ key }` ]: objectBit[ key ] } ) //append object with it’s path as key
)
)
}( object ) )
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment