【问题标题】:How to parse JSON having nested arrays in javascript or jquery如何在 javascript 或 jquery 中解析具有嵌套数组的 JSON
【发布时间】:2019-11-01 01:43:55
【问题描述】:

我想像下面这样解析 JSON

{
   "nodeId":3892718504,
   "root":true,
   "subs":[
      {
         "nodeId":3892717286
      },
      {
         "nodeId":3892716092,
         "subs":[
            {
               "nodeId":3892715856,
               "subs":[
                  {
                     "nodeId":3892718592,
                     "subs":[
                        {
                           "nodeId":3892717580
                        }
                     ]
                  }
               ]
            }
         ]
      },
      {
         "nodeId":3892717497
      }
   ]
}

每个节点都可以有子节点,这些子节点可以有可以有自己的子节点的节点。我想要的只是一个具有所有nodeId的数组,我如何解析这个JSON,以便一个名为nodes_list的数组填充所有nodeId。 我可以使用 javascript 或 jquery。

我正在尝试以下方法来获取 nodeId 数组

jQuery.each(response.topology, function(i,obj) {
  if(i == "nodeId") {
    node_list.push(obj)
  }
  if(i == "subs"){
    jQuery.each(i, function(key,value) {
        if(i == "nodeId") {
            node_list.push(obj)
        }
    }
  }
});

我只需要一点关于它如何以迭代方式的提示。

【问题讨论】:

  • 您能否向我们展示您为完成该任务所做的努力?
  • 您似乎将“解析”与“将解析的数据结构转换为不同的数据结构”混淆了。您似乎也没有做出任何努力或研究如何做到这一点。
  • 我试图从这个 JSON 中获取结构化数据
  • 请我知道我问这样的问题很愚蠢,但我所需要的只是在每次迭代中检查 subs 的循环和

标签: javascript jquery arrays json loops


【解决方案1】:

这可以通过函数发生器来完成。

也许不是最令人愉快的方法,但我很确定其他解决方案已经暗示使用其他方式,所以这里是使用生成器的解决方案。

PS:小心浏览器支持:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/yield

const input = {
   "nodeId":3892718504,
   "root":true,
   "subs":[
      {
         "nodeId":3892717286
      },
      {
         "nodeId":3892716092,
         "subs":[
            {
               "nodeId":3892715856,
               "subs":[
                  {
                     "nodeId":3892718592,
                     "subs":[
                        {
                           "nodeId":3892717580
                        }
                     ]
                  }
               ]
            }
         ]
      },
      {
         "nodeId":3892717497
      }
   ]
};

function* nodeLookup(obj) {
  if (obj.nodeId) yield obj.nodeId;
  if (obj.subs) for (var i = 0; i < obj.subs.length; i++) yield *nodeLookup(obj.subs[i]);
};

const node_ids = [...nodeLookup(input)];
console.log(node_ids);

【讨论】:

  • 这似乎是目前唯一可行的解​​决方案,非常感谢您的帮助,如果没有您的帮助,我将永远坚持从嵌套循环中提取数据。我也很抱歉没有在第一次发布我的失败尝试。
  • @RishabhGusain 您可以通过仅使用(上面已经可用的)递归来避免使用函数生成器。我决定遵循 function* 方法,因为您可以根据需要轻松包装结果(在这种情况下,扩展运算符 ... 用于将函数生成器的结果累积到一个数组中)。如果您愿意,可以通过删除函数生成器并手动添加累加器来转换上述代码。
  • @RishabhGusain:很好,你这次没有发布你的尝试,因为你回去添加它......如果你从中吸取教训并记住将来这样做。
  • 这种方法最符合现代 Javascript
【解决方案2】:

递归很简单:

const gatherIds = ({nodeId, subs}, results = []) => subs
  ? [...results, nodeId, ...(subs .flatMap (sub => gatherIds (sub, results) ))]
  : [...results, nodeId]

const response = {"nodeId": 3892718504, "root": true, "subs": [{"nodeId": 3892717286}, {"nodeId": 3892716092, "subs": [{"nodeId": 3892715856, "subs": [{"nodeId": 3892718592, "subs": [{"nodeId": 3892717580}]}]}]}, {"nodeId": 3892717497}]}

console .log (
  gatherIds (response)
)

如果您的目标环境为don't support flatmap,那么填充很容易。

【讨论】:

    【解决方案3】:

    只需使用递归来迭代 subs

    var nodeIds = [];
    if (data.nodeId) nodeIds.push(data.nodeId);
    function fetchNodeIds (subs) {
        if (!subs.length) return cb([]);
        var abc = [];
        subs.forEach(function (sub) {
            abc.push(sub.nodeId);
            if (sub.subs && sub.subs.length) abc = abc.concat(fetchNodeIds(sub.subs))
        });
        return abc;
    }
    nodeIds = nodeIds.concat(fetchNodeIds(data.subs));
    console.log('--All nodeIds--', nodeIds)
    

    【讨论】:

    • 当然,但请参阅我的答案以获得更简单的递归。
    猜你喜欢
    • 2016-10-17
    • 2015-06-15
    • 1970-01-01
    • 1970-01-01
    • 2019-07-10
    • 1970-01-01
    • 2019-12-30
    • 2014-02-26
    • 1970-01-01
    相关资源
    最近更新 更多