Javascript 遍历到子节点并查找属性(最多n个级别)

Javascript 遍历到子节点并查找属性(最多n个级别),javascript,json,recursion,Javascript,Json,Recursion,我们有一个JSON文件: var response = { "Status": "Met", "Text": "Text1", "Id": "AAA", "ContentItems": [ { "Selected": true, "Text": "Text2", "Id": "BBB" }, { "Status": "Met", "Text": "Text3", "Id": "CCC"

我们有一个JSON文件:

var response = {
  "Status": "Met",
  "Text": "Text1",
  "Id": "AAA",
  "ContentItems": [
    {
      "Selected": true,
      "Text": "Text2",
      "Id": "BBB"
    },
    {
      "Status": "Met",
      "Text": "Text3",
      "Id": "CCC",          
      "ContentItems": [
        {
          "Selected": true,
          "Text": "Text5",
          "Id": "DDD"
        },
        {
          "Status": "Met",
          "Text": "Text6",
          "Id": "EEE",
          "ContentItems": [
            {
              "Selected": true,
              "Text": "Text7",
              "Id": "FFF"
            },
            {
              "Selected": true,
              "Text": "Text8",
              "Id": "GGG"
            },
            {
              "Status": "Met",
              "Text": "Text9",
              "Id": "III",
              "ContentItems": [
                {
                  "Status": "Met",
                  "Text": "Text11",
                  "Id": "JJJ",
                  "ContentItems": [
                    {
                      "Text": "Text12",
                      "Id": "77"
                    },
                    {
                      "Status": "Met",
                      "Text": "Text13",
                      "Id": "10",
                      "ContentItems": [
                        {
                          "Text": "Text14",
                          "Id": "45"
                        },
                        {
                          "Selected": true,
                          "Text": "Text15",
                          "Id": "87"
                        },
                        {
                          "Selected": true,
                          "Text": "Text16",
                          "Id": "80"
                        }
                      ]
                    }                            
                  ]
                },
                {
                  "Status": "Met",
                  "Text": "Text17",
                  "Id": "KKK",
                  "ContentItems": [
                    {
                      "Text": "Text18",
                      "Id": "12"
                    },
                    {
                      "Status": "NotMet",
                      "Text": "Text19",
                      "Id": "14",
                      "ContentItems": [
                        {
                          "Text": "Text20",
                          "Id": "55"
                        },
                        {
                          "Selected": true,
                          "Text": "Text21",
                          "Id": "98"
                        }
                      ]
                    }                            
                  ]
                }
              ]
            }
          ]
        }
      ]
    }
  ]
};
从JSON文件中,我们需要以下内容:

1.如果所有“状态”均为“满足”,则返回true

2.如果任何“状态”为“未满足”,则返回false

因为子节点可以是任何级别的深度;我使用递归函数遍历每个节点,然后在子节点上循环并递归调用该函数

我尝试了这段代码,但没有按预期工作

function isStatusMet(response) {
  if (response.Status == 'NotMet') {
    return false;
  } else {
    if (response.ContentItems) {
      if(Array.isArray(response.ContentItems)) {
        for(var i = 0; i < response.ContentItems.length;i++) {
          if (response.ContentItems[i].ContentItems) {
            return isStatusMet(response.ContentItems[i]);
          } else {
            if (response.ContentItems[i].Status == 'NotMet') {
              return false;
            } else {
              continue;
            }
          }
        }
        return true;
      }
    } 
  }
}
函数isStatusMet(响应){
如果(response.Status==“NotMet”){
返回false;
}否则{
if(response.ContentItems){
if(Array.isArray(response.ContentItems)){
对于(var i=0;i
语句
返回isStatusMet(response.ContentItems[i])将在任何状态下提前退出。如果递归调用回答
false
,则它只应返回
false
,否则循环需要继续

将其更改为:

if (response.ContentItems[i].ContentItems) {
    if (!isStatusMet(response.ContentItems[i])) return false;
}
如果
ContentItems
是一个数组,则可以使用并递归使用它

var data={Status:“Met”,Text:“Text1”,Id:“AAA”,ContentItems:[{Selected:true,Text:“Text2”,Id:“BBB”},{Status:“Met”,Text:“Text3”,Id:“CCC”,ContentItems:[{Selected:true,Text:“Text5”,Id:“DDD”},{Status:“Met”,Text:“Text6”,Id:“EEE”,ContentItems:[{Selected:true,Text:“Text7”,Id:“FFF”},{所选:true,Text:“Text8”,Id:“GGG”},{状态:“Met”,Text:“Text9”,Id:“III”,ContentItems:[{状态:“Met”,Text:“Text11”,Id:“JJJ”,ContentItems:[{状态:“Text12”,Id:77},{状态:“Met”,Text:“Text13”,Id:10,ContentItems:[{所选:true,Text:“Text15”,Id:87},{所选:true,Text:Text:“Text16”,Id:80}]},{Status:“Met”,Text:“Text17”,Id:“KKK”,ContentItems:[{Text:“Text18”,Id:12},{Status:“NotMet”,Text:“Text19”,Id:14,ContentItems:[{Text:“Text20”,Id:55},{Selected:true,Text:“Text21”,Id:98}]}}},
结果=[数据]。每个函数(iter(a){
返回a.Status!='NotMet'&(!Array.isArray(a.ContentItems)| | a.ContentItems.every(iter));
});

console.log(result);
的可能重复如果您从for循环内部返回,则该循环中的所有后续交互都将被跳过,因此您的代码只检查每个node.Array.every()的第一个子级在这里应该非常有用。如果您已经在使用jQuery,这可能对您想要的任何属性都很有用:将上面的JSON粘贴到演示的文本区域,并将属性输入字段更改为属性状态(case sensitve)。勾选避免重复复选框,然后单击Filter JSON按钮以给出结果。
var isStatusMet = function isStatusMet( data ) {
    // If the status is NotMet, we finish immediately
    if (data.Status === 'NotMet') return false;
    // Since only nodes with ContentItems have a status, we check if the node has children and recursively check if every child has no Status of NotMet
    else if (data.hasOwnProperty('ContentItems')) return data.ContentItems.every(isStatusMet);
    // We're dealing with a child without Status or Childnodes, so we just return true.
    // Since the status in not met and the parent node of this node expects in its 'every' loop that we only return false for nodes that have Status NotMet, this makes the recusion work.
    else return true;
};

var met = isStatusMet(response);

console.log(met);