How to convert this nested object to a flat object?

Sorry, I don’t know how to formulate the title of the question. Please help change if possible.

I have an object like this:

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

I want to do this:

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

jQuery is fine too. I know for a nested object, I can use abde to get hahaha , but today I have to use it as a['bde'] -_- !!! How can i achieve this? Thanks in advance:)

+7
source share
8 answers

You can use the recursive function to scan the object and align it for you.

 var test = { a: 'jack', b: { c: 'sparrow', d: { e: 'hahaha' } } }; function dive(currentKey, into, target) { for (var i in into) { if (into.hasOwnProperty(i)) { var newKey = i; var newVal = into[i]; if (currentKey.length > 0) { newKey = currentKey + '.' + i; } if (typeof newVal === "object") { dive(newKey, newVal, target); } else { target[newKey] = newVal; } } } } function flatten(arr) { var newObj = {}; dive("", arr, newObj); return newObj; } var flattened = JSON.stringify(flatten(test)); console.log(flattened); 
+18
source

Alternative recursive implementation. It just seemed to me that I was writing one implementation myself, although the current ones are already really good.

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

  • If it is an object, we repeat each key of the object.
  • Otherwise, we add it to 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]), {}); 

NPM flat pack

Or you can just use the flat npm package , which is a well-known test library.

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

⬑ I would use this in serious code.

[Extra] Inactive function call 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> 
+4
source

Recursive is the best solution for this case.

 function flatten(input, reference, output) { output = output || {}; for (var key in input) { var value = input[key]; key = reference ? reference + '.' + key : key; if (typeof value === 'object' && value !== null) { flatten(value, key, output); } else { output[key] = value; } } return output; } var result = flatten({ a: 'jack', b: { c: 'sparrow', d: { e: 'hahaha' } } }); document.body.textContent = JSON.stringify(result); 
+3
source

You can view the cycles of object records . If value is an object, call the function recursively. Use flatMap to get a flat array of records.

Then use Object.fromEntries() to get the object from a flattened array of records

 const input = { a: 'jack', b: { c: 'sparrow', d: { e: 'hahaha' } } } const getEntries = (o, prefix = '') => Object.entries(o).flatMap(([k, v]) => Object(v) === v ? getEntries(v, '${prefix}${k}.') : [ ['${prefix}${k}', v] ] ) console.log( Object.fromEntries(getEntries(input)) ) 

Note : Object(v) === v returns true only for objects. typeof v === 'object' is also true for v = null .

+1
source

Verification with a recursive function, iterating over the keys of an object and searching if this value is an object. if so, make a call with the updated feature. Otherwise, add the found value to the result object.

 function getValues(o, a) { Object.keys(o).forEach(function (k) { if (typeof o[k] === 'object') { getValues(o[k], [].concat(a, k)); return; } result[[].concat(a, k).join('.')] = o[k]; }); } var object = { a: 'jack', b: { c: 'sparrow', d: { e: 'hahaha' } } }, result = {}; getValues(object); document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>'); 
0
source

Just an example of how to achieve this with ES6 features.

 const flatObject = obj => { const keys = Object.keys(obj) return keys.reduce((acc, k) => { const value = obj[k] return typeof value === 'object' ? {...acc, ...ObjectUtils.flatObject(value)} : {...acc, [k]: value} } , {}) } 
0
source

Another approach using ES6.

 const obj = { a: "jack", b: { c: "sparrow", d: { e: "hahaha" } } }; function flattenObj(value, currentKey) { let result = {}; Object.keys(value).forEach(key => { const tempKey = currentKey ? '${currentKey}.${key}' : key; if (typeof value[key] !== "object") { result[tempKey] = value[key]; } else { result = { ...result, ...flattenObj(value[key], tempKey) }; } }); return result; } console.log(flattenObj(obj)); 
0
source

You do not need to make changes, you can access it, like JsonObject.bc , to get data from the c field.

Take a look at this http://www.mkyong.com/javascript/how-to-access-json-object-in-javascript/ .

-2
source

Source: https://habr.com/ru/post/1239435/


All Articles