Sudhakar
Sudhakar

Reputation: 3094

transforming json using recursive function

I'm trying to transform this JSON into array so that I can simply list them as key-value pairs in html. The JSON has nested properties which I want to retain but I want to stringify only those objects that contain "units" and "value". All others should be listed as children items. Please help figure what I'm doing wrong.

Here's the json input:

  {
  "clusterName": "ml6.engrlab.com-cluster",
  "statusProperties": {
    "loadProperties": {
      "loadDetail": {
        "restoreWriteLoad": {
          "value": 0,
          "units": "sec/sec"
        },
      },
      "totalLoad": {
        "value": 0.0825921967625618,
        "units": "sec/sec"
      }
    },
    "secure": {
      "value": false,
      "units": "bool"
    },
    "statusDetail": {
      "licenseKeyOption": [
        {
          "value": "conversion",
          "units": "enum"
        },
        {
          "value": "failover",
          "units": "enum"
        }
      ],
      "connectPort": 7999,
      "softwareVersion": {
        "value": 9000100,
        "units": "quantity"
      }
    },
    "rateProperties": {
      "rateDetail": {
        "largeReadRate": {
          "value": 0,
          "units": "MB/sec"
        }
      },
      "totalRate": {
        "value": 67.2446365356445,
        "units": "MB/sec"
      }
    },
    "online": {
      "value": true,
      "units": "bool"
    },
    "cacheProperties": {
      "cacheDetail": {
        "tripleCachePartitions": {
          "tripleCachePartition": [
            {
              "partitionSize": 768,
              "partitionBusy": 0,
              "partitionUsed": 0,
              "partitionFree": 100
            }
          ]
        }
      }
    }
  }
}

my code

function isNested(obj) {
if(!obj) return false;

let propArry = Object.keys(obj)
for(let i=0; i<propArry.length; i++){
  if(obj[propArry[0]].constructor.name === 'Object') return true
}
  return false;
} 


function getKeyValueAsChildren(obj) {
  let vals = [];
  for(let key in obj) {
    if(obj.hasOwnProperty(key)){
      vals.push({key:key, value: obj[key]})
    }
  }
  return vals
}

function valueAsString(obj) {
  if(typeof obj !== 'object') return obj;

  return `${obj['value']} ${obj['units']}`
}

function getChildren(key, obj) {
   if(Object.keys(obj).sort().toString() === "units,value"){
         return {key: key, value: valueAsString(obj)}            
     } else {
         return {key: key, children: getKeyValueAsChildren(obj) }            
   }
}

function getValues(properties, values = []) {
for(let key in properties) {
    if(properties.hasOwnProperty(key)) {
      let value =  properties[key]
      if(typeof value !== 'object') {
        values.push({key: key, value: value})  
      } else if(Array.isArray(value)){
        let children = []
        value.map(v => {
          children.push(getChildren(key, v))  
        })  
        values.push({key: `${key}List`, children: children})
      } 
      else if(value.constructor.name === 'Object' && isNested(value)){
        // I THINK THE MAIN PROBLEM IS HERE
        let keys = Object.keys(value)
        let children = [];
        keys.forEach(key => {
          children.push({key: key, children: getValues(value[key])})
        })
        values.push({key: key, children: children})
      } 
       else {
          values.push(getChildren(key, value))
      }
    }
}
return values
}

getValues(hostProperties)

this returns

    [
    {
        "key": "clusterName",
        "value": "ml6.engrlab.com-cluster"
    },
    {
        "key": "statusProperties",
        "children": [
            {
                "key": "loadProperties",
                "children": [
                    {
                        "key": "loadDetail",
                        "children": [
                            {
                                "key": "restoreWriteLoad",
                                "children": [
                                    {
                                        "key": "value",
                                        "value": 0
                                    },
                                    {
                                        "key": "units",
                                        "value": "sec/sec"
                                    }
                                ]
                            }
                        ]
                    },
                    {
                        "key": "totalLoad",
                        "value": "0.0825921967625618 sec/sec"
                    }
                ]
            },
            {
                "key": "secure",
                "children": [
                    {
                        "key": "value",
                        "value": false
                    },
                    {
                        "key": "units",
                        "value": "bool"
                    }
                ]
            },
            {
                "key": "statusDetail",
                "children": [
                    {
                        "key": "licenseKeyOptionList",
                        "children": [
                            {
                                "key": "licenseKeyOption",
                                "value": "conversion enum"
                            },
                            {
                                "key": "licenseKeyOption",
                                "value": "failover enum"
                            }
                        ]
                    },
                    {
                        "key": "connectPort",
                        "value": 7999
                    },
                ]
            },
            {
                "key": "rateProperties",
                "children": [
                    {
                        "key": "rateDetail",
                        "children": [
                            {
                                "key": "largeReadRate",
                                "children": [
                                    {
                                        "key": "value",
                                        "value": 0
                                    },
                                    {
                                        "key": "units",
                                        "value": "MB/sec"
                                    }
                                ]
                            }
                        ]
                    },
                    {
                        "key": "totalRate",
                        "value": "67.2446365356445 MB/sec"
                    }
                ]
            },
            {
                "key": "online",
                "children": [
                    {
                        "key": "value",
                        "value": true
                    },
                    {
                        "key": "units",
                        "value": "bool"
                    }
                ]
            },
            {
                "key": "cacheProperties",
                "children": [
                    {
                        "key": "cacheDetail",
                        "children": [
                            {
                                "key": "tripleCachePartitions",
                                "children": [
                                    {
                                        "key": "tripleCachePartitionList",
                                        "children": [
                                            {
                                                "key": "tripleCachePartition",
                                                "children": [
                                                    {
                                                        "key": "partitionSize",
                                                        "value": 768
                                                    },
                                                    {
                                                        "key": "partitionBusy",
                                                        "value": 0
                                                    },
                                                    {
                                                        "key": "partitionUsed",
                                                        "value": 0
                                                    },
                                                    {
                                                        "key": "partitionFree",
                                                        "value": 100
                                                    }
                                                ]
                                            }
                                        ]
                                    }
                                ]
                            }
                        ]
                    }
                ]
            }
        ]
    }
]

but I need this

[
{
    "key": "clusterName",
    "value": "ml6.engrlab.com-cluster"
},
{
    "key": "statusProperties",
    "children": [
        {
            "key": "loadProperties",
            "children": [
                {
                    "key": "loadDetail",
                    "children": [
                        {
                            "key": "restoreWriteLoad",
                            "value": "0 sec/sec"
                        }
                    ]
                },
                {
                    "key": "totalLoad",
                    "value": "0.0825921967625618 sec/sec"
                }
            ]
        },
        {
            "key": "secure",
            "value": "false bool"
        },
        {
            "key": "statusDetail",
            "children": [
                {
                    "key": "licenseKeyOptionList",
                    "children": [
                        {
                            "key": "licenseKeyOption",
                            "value": "conversion enum"
                        },
                        {
                            "key": "licenseKeyOption",
                            "value": "failover enum"
                        }
                    ]
                },
                {
                    "key": "connectPort",
                    "value": 7999
                }
            ]
        },
        {
            "key": "rateProperties",
            "children": [
                {
                    "key": "rateDetail",
                    "children": [
                        {
                            "key": "largeReadRate",
                            "value": "0 MB/sec"
                        }
                    ]
                },
                {
                    "key": "totalRate",
                    "value": "67.2446365356445 MB/sec"
                }
            ]
        },
        {
            "key": "online",
            "value": "true bool"
        },
        {
            "key": "cacheProperties",
            "children": [
                {
                    "key": "cacheDetail",
                    "children": [
                        {
                            "key": "tripleCachePartitions",
                            "children": [
                                {
                                    "key": "tripleCachePartitionList",
                                    "children": [
                                        {
                                            "key": "tripleCachePartition",
                                            "children": [
                                                {
                                                    "key": "partitionSize",
                                                    "value": 768
                                                },
                                                {
                                                    "key": "partitionBusy",
                                                    "value": 0
                                                },
                                                {
                                                    "key": "partitionUsed",
                                                    "value": 0
                                                },
                                                {
                                                    "key": "partitionFree",
                                                    "value": 100
                                                }
                                            ]
                                        }
                                    ]
                                }
                            ]
                        }
                    ]
                }
            ]
        }
    ]
}

]

Upvotes: 2

Views: 346

Answers (1)

Matt Way
Matt Way

Reputation: 33161

You might have to run more tests, as what you require seems quite arbitrary, but I believe this function does what you are looking for. It works in a similar way to yours, by simply recursing the tree, and checking for object types, and if the special case is matched.

function toKeyValue(obj) {
  return Object.keys(obj).map(k => {    
    var value = obj[k]
    var key = k 
    var valueName = 'children'
    if(Array.isArray(value)){
      key = k + 'List'
      value = value.map(toKeyValue)
    }else if(value !== null && typeof value === 'object'){
      // check for special case
      if(Object.keys(value).sort().toString() === "units,value"){
        value = value.value + ' ' + value.units
        valueName = 'value'
      }else{
        value = toKeyValue(value)
      }      
    }else{
      valueName = 'value'
    }
    return {
      key: key,
      [valueName]: value
    }
  })
}

Fiddle here

Upvotes: 1

Related Questions