How to change deepest object to string value if it is empty object in JavaScript
Suppose I have this object:
{CONN_INFO: {CFGSwitch: {412: {}}}}
It has a depth of 4. I want to reassign the key 412
to "{}"
so that the final object is
{CONN_INFO: {CFGSwitch: {412: "{}"}}}
Function for checking depth:
function checkDepth(object) {
var level = 1;
var key;
for(key in object) {
if (!object.hasOwnProperty(key)) continue;
if(typeof object[key] == 'object'){
var depth = checkDepth(object[key]) + 1;
level = Math.max(depth, level);
}
}
return level;
}
I have something like this, but I'm not sure if it is optimal or will work for all cases. Would be thanked for entering.
function checkIfLastLevelEmpty(obj, depth) {
for (var key in obj) {
var val = obj[key];
if (Object.keys(obj[key]).length === 0) {
obj[key] = "{}";
}
else {
if (depth >0) {
checkIfLastLevelEmpty(val, depth-1);
}
}
}
}
source to share
First, combine some knowledge:
How do I check for an empty JavaScript object?
The above question has an amazing answer with many options in it, I'm going to edit snippets to form a couple of functions:
function isObject (obj) {
return obj.constructor === Object;
}
function isEmptyObject (obj) {
return Object.keys(obj).length === 0 && isObject(obj);
}
Ace. Now, assuming you have a very linear object structure, it's not a complex array and doesn't care about depth (just that it's empty) lets you loop the function through the tree.
function convertEmptyObjects (obj, currentDepth) {
currentDepth = currentDepth || 0;
for (var key in obj) {
var val = obj[key];
if (isObject(val)) {
if (isEmptyObject(val)) {
obj[key] = "{}";
console.log("Defeated boss ("+ key +") on level "+ currentDepth +"!");
}else{
convertDeepestEmptyObject (val, currentDepth + 1);
}
}
}
return obj;
}
Lets test this on a terrible looking object:
var testObject = {
CONN_INFO: {
CFGSwitch: {
412: {}, // Level 2
413: {
content: {} // Level 3
}
},
DummySwitch: {} // Level 1
},
TEST_CONN_INFO: {
CFGSwitch: {
414: {}, // Level 2
415: {
content: {
host: "google",
port: "8080",
protocol: {} // Level 4
}
}
}
},
STAGING_CONN_INFO: {} // Level 0
}
convertEmptyObjects(testObject);
JSON.stringify(testObject)
/* Output:
* Defeated boss (412) on level 2!
* Defeated boss (content) on level 3!
* Defeated boss (DummySwitch) on level 1!
* Defeated boss (414) on level 2!
* Defeated boss (protocol) on level 4!
* Defeated boss (STAGING_CONN_INFO) on level 0!
*/
// Result:
{
"CONN_INFO": {
"CFGSwitch": {
"412": "{}", // Empty String {}
"413": {
"content": "{}" // Empty String {}
}
},
"DummySwitch": "{}" // Empty String {}
},
"TEST_CONN_INFO": {
"CFGSwitch": {
"414": "{}", // Empty String {}
"415": {
"content": {
"host": "google",
"port": "8080",
"protocol": "{}" // Empty String {}
}
}
}
},
"STAGING_CONN_INFO": "{}" // Empty String {}
}
There you have it.
source to share
deeper=obj=>(Object.keys(obj[Object.keys(obj)[0]]).length&&deeper(obj[Object.keys(obj)[0]])&&true)||(obj[Object.keys(obj)[0]]="{}");
var obj={CONN_INFO: {CFGSwitch: {412: {}}}};
deeper(obj);
console.log(obj);
http://jsbin.com/nidahuhema/edit?console
Why do you check depth and then go into it? can't you do it all in one?
Long form of top code:
function deeper(obj){
if(Object.keys(Object.values(obj)[0]).length){ // if the child object has properties
return deeper(Object.values(obj)[0]);
}
obj[Object.keys(obj)[0]]="{}";
}
source to share