3

I have some attributes from a nested object that is inside the parent object but I would like to merge nested object with the parent object to be flatten.

Original object:

enrollment = {
 user: {
 id: 'string',
 name: 'string'
 },
 finished: 'boolean',
 path: 'string'
}

expected flatten object:

user: {
 id: 'string',
 name: 'string',
 finished: 'boolean',
 path: 'string'
}
Nilanka Manoj
3,7474 gold badges21 silver badges52 bronze badges
asked Apr 20, 2020 at 22:29

6 Answers 6

4

You can recursively build object any number of nested objects. So, this function is not your case dependent:

var enrollment = {
user: {
 id: 'string',
 name: 'string'
},
finished: 'boolean',
path: 'boolean'
}
var enrollment2 = {
user: {
 id: 'string',
 name: 'string'
},
test: {
 test1: {
 test2: {
 val0:'val0',
 test4: { //3rd level nested object for example
 val1: 'val1',
 val2: 'val2'
 }
 }
 }
},
finished: 'boolean',
path: 'boolean'
}
const flat = (obj, out) => {
 Object.keys(obj).forEach(key => {
 if (typeof obj[key] == 'object') {
 out = flat(obj[key], out) //recursively call for nesteds
 } else {
 out[key] = obj[key] //direct assign for values
 }
 })
 return out
}
console.log(flat(enrollment, {}))
console.log(flat(enrollment2, {}))

answered Apr 21, 2020 at 1:31
Sign up to request clarification or add additional context in comments.

1 Comment

In the general use case - in case of null value, typeof obj[key] return 'object' and TypeError exception will be thrown in the inner recursion.
4

I needed something that avoids rewriting keys with the same name that were in different levels in the original object. So I wrote the following:

const flattenObject = (obj, parentKey = '') => {
 if (parentKey !== '') parentKey += '.';
 let flattened = {};
 Object.keys(obj).forEach((key) => {
 if (typeof obj[key] === 'object' && obj[key] !== null) {
 Object.assign(flattened, flattenObject(obj[key], parentKey + key))
 } else {
 flattened[parentKey + key] = obj[key]
 }
 })
 return flattened;
}
var test = {
 foo: 'bar',
 some: 'thing',
 father: {
 son1: 'son1 value',
 son2: {
 grandchild: 'grandchild value',
 duplicatedKey: 'note this is also used in first level',
 },
 },
 duplicatedKey: 'note this is also used inside son2',
}
let flat = flattenObject(test);
console.log(flat);
// how to access the flattened keys:
let a = flat['father.son2.grandchild'];
console.log(a);

Also checks if the object is null, as I was having some problems with that in my usage.

answered Feb 9, 2021 at 13:46

Comments

1

Here's a quick and dirty way to flatten your object:

var enrollment = {
 user: {
 id: 'string',
 name: 'string',
 },
 fineshed: true,
 path: false,
};
var user = Object.assign(enrollment.user);
user.fineshed = enrollment.fineshed;
user.path = enrollment.path;

For a generic method with a couple of caveats of no shared key names and only flattening 1 level of depth:

var enrollment = {
	user: {
		id: 'string',
		name: 'string',
	},
	fineshed: true,
	path: false,
};
const flatten = (object) => {
	let value = {};
	for (var property in object) {
		if (typeof object[property] === 'object') {
			for (var p in object[property]) {
				value[p] = object[property][p];
			}
		} else {
			value[property] = object[property];
		}
	}
	return value;
};
let user = flatten(enrollment);
console.log(user);

answered Apr 20, 2020 at 23:01

Comments

1

using recursion and reduce.

note that if value itself is an array containing objects, you might want add another check like !Array.isArray(value) depending on your case

function flatObj(obj) {
 return Object.entries(obj).reduce(
 (flatted, [key, value]) =>
 typeof value == "object"
 ? { ...flatted, ...flatObj(value) }
 : { ...flatted, [key]: value },
 {}
 );
}
answered Apr 6, 2022 at 9:19

Comments

0

Just want a single Object:

const enrollment = {
 user: {
 id: 'string',
 name: 'string'
 },
 finished: 'boolean',
 path: 'boolean'
}
function propsToUser(enrollObj){
 const u = {...enrollObj.user};
 for(let i in enrollObj){
 if(i !== 'user')u[i] = enrollObj[i];
 }
 return u;
}
const user = propsToUser(enrollment);
console.log(user);

answered Apr 21, 2020 at 1:20

Comments

0

Below code snippet takes nested input object like this :

{
 name:'Namig',
 surname:'Hajiyev',
 address:{
 city:'Sumgait',
 country:'Azerbaijan',
 geo: {
 lat:'40.5897200',
 long:'49.6686100'
 }
 }
 }

and returns result flattened object like this:

{
 "name": "Namig",
 "surname": "Hajiyev",
 "address.city": "Sumgait",
 "address.country": "Azerbaijan",
 "address.geo.lat": "40.5897200",
 "address.geo.long": "49.6686100"
}

Here is my code :

function flattenObject(obj, newObj, prefix) {
 newObj = newObj || {};
 prefix = prefix || "";
 for (var key in obj) {
 if (obj.hasOwnProperty(key)) {
 const type = typeof obj[key];
 const newKey = !!prefix ? prefix + "." + key : key;
 if (type === "string") {
 newObj[newKey] = obj[key];
 }
 else if (type === "object") {
 flattenObject(obj[key], newObj, newKey);
 }
 }
 }
 return newObj;
}
var obj = {
 name:'Namig',
 surname:'Hajiyev',
 address:{
 city:'Sumgait',
 country:'Azerbaijan',
 geo: {
 lat:'40.5897200',
 long:'49.6686100'
 }
 }
}
console.log(flattenObject(obj));

answered Apr 2, 2021 at 6:48

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.