Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to convert this nested object into a flat object?

Tags:

Sorry I don't know how to phrase the question title. Please help edit if possible.

I have an object like this:

{     a: 'jack',     b: {         c: 'sparrow',         d: {            e: 'hahaha'         }     } } 

I want to make it look like:

{     'a': 'jack',     'b.c': 'sparrow',     'b.d.e': 'hahaha' }  // so that I can use it this way: a['b.d.e'] 

jQuery is ok too. I know for the nested object, I can use a.b.d.e to get hahaha, but today I have to use it like a['b.d.e'] -_-!!! How can I achieve this? Thanks in advance :)

like image 201
shrekuu Avatar asked Dec 29 '15 15:12

shrekuu


People also ask

How do you flatten nested objects?

Use the concat() Method to Flatten an Object in JavaScript This example will set an object with an array object, a normal object, and a nested object. We will flatten the entire object with the help of the reduce() method and concat() method. Object.

Which method is used to convert nested arrays to objects?

toString() method is used to convert: an array of numbers, strings, mixed arrays, arrays of objects, and nested arrays into strings.

What does it mean to flatten an object?

To flatten a collection means to place them into a single object.


2 Answers

You could use a recursive function to crawl the object and flatten it for you.

var test = {      a: 'jack',      b: {          c: 'sparrow',          d: {              e: 'hahaha'          }      }  };    function traverseAndFlatten(currentNode, target, flattenedKey) {      for (var key in currentNode) {          if (currentNode.hasOwnProperty(key)) {              var newKey;              if (flattenedKey === undefined) {                  newKey = key;              } else {                  newKey = flattenedKey + '.' + key;              }                var value = currentNode[key];              if (typeof value === "object") {                  traverseAndFlatten(value, target, newKey);              } else {                  target[newKey] = value;              }          }      }  }    function flatten(obj) {      var flattenedObject = {};      traverseAndFlatten(obj, flattenedObject);      return flattenedObject;  }    var flattened = JSON.stringify(flatten(test));  console.log(flattened);
like image 167
Marie Avatar answered Sep 19 '22 22:09

Marie


An alternative recursive implementation. I just felt like writing one implementation myself, even though the current ones are already really good.

The recursive function checks whether the key is of type 'object'.

  • If it's an object, we iterate by each object's key.
  • Else, we add it into our result object.
function flat(res, key, val, pre = '') {   const prefix = [pre, key].filter(v => v).join('.');   return typeof val === 'object'     ? Object.keys(val).reduce((prev, curr) => flat(prev, curr, val[curr], prefix), res)     : Object.assign(res, { [prefix]: val}); } return Object.keys(input).reduce((prev, curr) => flat(prev, curr, input[curr]), {}); 

Flat NPM package

Or you can simply use flat npm package, which is a well known tested library.

var flatten = require('flat') flatten(obj); 

⬑ I would use this in serious code.

[Extra] Neater call to the function above

function flatObject(input) {   function flat(res, key, val, pre = '') {     const prefix = [pre, key].filter(v => v).join('.');     return typeof val === 'object'       ? Object.keys(val).reduce((prev, curr) => flat(prev, curr, val[curr], prefix), res)       : Object.assign(res, { [prefix]: val});   }    return Object.keys(input).reduce((prev, curr) => flat(prev, curr, input[curr]), {}); }  const result = flatObject(input); 

[Extra] Demo

http://codepen.io/zurfyx/pen/VpErja?editors=1010

function flatObject(input) {    function flat(res, key, val, pre = '') {      const prefix = [pre, key].filter(v => v).join('.');      return typeof val === 'object'        ? Object.keys(val).reduce((prev, curr) => flat(prev, curr, val[curr], prefix), res)        : Object.assign(res, { [prefix]: val});    }      return Object.keys(input).reduce((prev, curr) => flat(prev, curr, input[curr]), {});  }    const result = flatObject({      a: 'jack',      b: {          c: 'sparrow',          d: {             e: 'hahaha'          }      }  });    document.getElementById('code').innerHTML = JSON.stringify(result, null, 2);
<pre><code id="code"></code></pre>
like image 30
zurfyx Avatar answered Sep 20 '22 22:09

zurfyx