如何在javascript或jQuery中解析具有嵌套数组的JSON

时间:2019-06-18 12:01:49

标签: javascript jquery arrays json loops

我想像下面那样解析JSON

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

每个节点可以具有子节点,而这些子节点可以具有可以具有自己的子节点的节点。我想要的只是一个具有所有nodeId的数组,如何解析此JSON,以便用所有nodeId填充一个名为nodes_list的数组。 我可以使用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)
        }
    }
  }
});

我只需要一些关于如何迭代的提示。

3 个答案:

答案 0 :(得分:4)

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

也许不是最有趣的方法,但是我很确定其他解决方案已经暗示要使用其他方式,因此这里是使用生成器的解决方案。

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

答案 1 :(得分:2)

只需使用递归来遍历子项

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)

答案 2 :(得分:1)

直接进行递归操作即可:

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,则填充非常容易。