【问题标题】:Using recursion to modify JSON使用递归修改 JSON
【发布时间】:2015-02-17 15:02:36
【问题描述】:

我正在使用 AngularJS 模板将 JSON 显示为列表/树结构。

我的 JSON 深度未知。在大多数情况下,我的代码都有效。到目前为止,我遇到的只有一个案例不起作用。

我的 JSON 示例:

[
   {
      "type":"image",
      "bitmapname":{
         "text":"Image_12.bmp"
      },
      "command":[
         {
            "type":"close",
            "text":"1234"
         },
         {
            "type":"place",
            "text":"company"
         },
         {
            "type":"key",
            "key": "Tab"
         },
         {
            "type":"keyboard",
            "text":"welcome",
            "command": [
               {
                  "type":"open",
                  "text":"1234"
               },
               {
                  "type":"home",
                  "text":"company"
               }
            ]
         }
      ]
   },
   {
      "type":"image",
      "bitmapname":{
         "text":"image_14.bmp"
      },
      "command":{
         "type":"move",
         "text":"right"
      }
   }
]

输出如下:

AngularJS 代码:

<script type="text/ng-template" id="xml.html">
    <!-- XML is coming from controller as a JSON shown in my sample -->
    <ul>
        <li ng-repeat="item in XML">

            [[ item["type"] ]]

            <div ng-include=" 'xml.html' " 
                onload="XML = item.command">
            </div>

        </li>
    </ul>

</script>

<div ng-include=" 'xml.html' ">

您可能注意到最后一个列表项是空的,因为 "command" 不是数组

我正在尝试创建一个递归函数,该函数将通过 JSON 并在我有 "command": {...} 的地方的一个元素 "command": [{...}] 上创建数组

任何人都可以提出一个解决方案,将对象转换为对象数组,只要我有长度为一的对象吗?

注意

我无法控制从 Django 支持的 JSON 发送。 Python 使用xmltodict 扩展将XML 转换为字典。只要 XML 标记没有子标记,它就不会创建列表。它只创建一个字典。

【问题讨论】:

  • 您能告诉我们为什么您的 JSON 没有始终如一地为 .command 属性使用数组吗?最好的解决方案是从一致的数据格式开始,而不是为不一致的数据格式寻找解决方法。
  • JSON 是从 XML 创建的。当 XML 中的“command”标签没有子标签时,将 XML 转换为 JSON 的 python 扩展不会创建数组
  • 我在使用自动 XML -> JSON 序列化时遇到了类似的问题。我认为一个好的解决方案是使用数据结构感知方法来序列化数据,但我已经添加了您要求的解决方法的答案。

标签: arrays json angularjs recursion


【解决方案1】:

这不是一个非常通用的方法,但应该可以满足您的要求:

function fixCommands(values) {
    values.filter(function (v) {
        return 'command' in v;
    })
    .forEach(function (v) {
        if(v.command.constructor === Array) {
            fixCommands(v.command);
        } else {
            v.command = [v.command];
        }
    });
}

jsfiddle example

【讨论】:

  • Tnx JLRishe,我会在我检查后告诉你
【解决方案2】:

您可以检查第一个项目是否是对象,如果它是一个对象,您可以对其进行循环,否则它是您在顶部提到的其他类型。例如

if(arr[i].command.length===undefined) -> so is string part
else -> is array part

【讨论】:

    猜你喜欢
    • 2016-10-20
    • 2020-05-04
    • 1970-01-01
    • 2019-09-06
    • 1970-01-01
    • 1970-01-01
    • 2017-04-06
    • 2021-12-05
    • 2014-04-21
    相关资源
    最近更新 更多