【问题标题】:transforming json using recursive function使用递归函数转换 json
【发布时间】:2017-08-23 15:18:45
【问题描述】:

我正在尝试将此 JSON 转换为数组,以便我可以简单地将它们列为 html 中的键值对。 JSON 具有我想保留的嵌套属性,但我只想对那些包含“单位”和“值”的对象进行字符串化。所有其他应列为子项。请帮助弄清楚我做错了什么。

这是 json 输入:

  {
  "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
            }
          ]
        }
      }
    }
  }
}

我的代码

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)

这会返回

    [
    {
        "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
                                                    }
                                                ]
                                            }
                                        ]
                                    }
                                ]
                            }
                        ]
                    }
                ]
            }
        ]
    }
]

但我需要这个

[
{
    "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
                                                }
                                            ]
                                        }
                                    ]
                                }
                            ]
                        }
                    ]
                }
            ]
        }
    ]
}

]

【问题讨论】:

  • 欢迎来到 StackOverflow。请阅读并遵循帮助文档中的发布指南。 Minimal, complete, verifiable example 适用于此。在您发布 MCVE 代码并准确描述问题之前,我们无法有效地帮助您。将输入示例缩减为简洁地展示问题的内容。
  • 另外,请解释一下为什么很多在线的JSON解析解决方案在这种情况下不能满足您的需求。
  • 嗨,这确实是我问题的最简化形式。 JSON比我发布的要大得多。我已经缩减到涵盖我需要处理的所有情况的小型集合。我正在寻找的输出格式非常适合我的需求

标签: javascript json recursion


【解决方案1】:

您可能需要运行更多测试,因为您的要求似乎很随意,但我相信此功能可以满足您的需求。它的工作方式与您的类似,只需递归树,检查对象类型,以及是否匹配特殊情况。

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
    }
  })
}

小提琴here

【讨论】:

  • 感谢马特,除了数组对象外,它几乎可以工作。例如:licenseKeyOption 列表包含未转换为字符串的“单位”和“值”对象
  • 数组条件中的行应该是map(toKeyValue)。所以不允许我更新。无论如何,我会接受你的回答。再次感谢!
  • 抱歉,写的很快。已更新您的修复程序。
猜你喜欢
  • 1970-01-01
  • 2023-01-23
  • 2014-05-24
  • 1970-01-01
  • 2016-01-06
  • 1970-01-01
  • 1970-01-01
  • 2023-01-13
  • 1970-01-01
相关资源
最近更新 更多