2017-02-03 2 views
2

У нас есть 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.Return верно, если все «Статус» «Встречается».

2.Return false if any "Status" is NotMet.

Поскольку дочерние узлы могут быть любого уровня глубокими; Я использовал функцию рекурсии для перехода к каждому узлу, и оттуда я перебираю дочерние узлы и рекурсивно вызываю функцию.

Я пробовал этот код, но он не работал должным образом.

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; 
     } 
    } 
    } 
} 
+0

Возможная Дубликат [доступ/процесс (вложенные) объекты, массивы или JSON] (http://stackoverflow.com/questions/11922383/access-process-nested- objects-arrays-or-json) – Teemu

+0

Если вы возвращаетесь изнутри цикла for, все последующие взаимодействия в этом цикле пропускаются, поэтому ваш код проверяет только первый ребенок каждого узла. Здесь очень полезно использовать Array.every(). – Shilly

+0

Если вы уже используете JQuery, это может быть полезно для любого свойства вы хотите: http://kapilkashyap.github.io/jquery-filter-json-plugin/ Вставить выше JSON в текстовое поле из demo и измените поле ввода свойств, чтобы статус был как свойство (case sensitve). Оставьте флажок «Избегать дубликатов» и нажмите кнопку «Фильтр JSON», чтобы дать вам результат. –

ответ

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

Заявление return isStatusMet(response.ContentItems[i]); сделает преждевременный выход в любом состоянии. Он должен возвращать только false, если рекурсивный вызов отвечает false, иначе цикл необходимо продолжить.

Изменить его к этому:

if (response.ContentItems[i].ContentItems) { 
    if (!isStatusMet(response.ContentItems[i])) return false; 
} 
1

Вы можете использовать Array#every и использовать его рекурсивным, если 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" }, { 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 }] }] }] }] }] }] }, 
 
    result = [data].every(function iter(a) { 
 
     return a.Status !== 'NotMet' && (!Array.isArray(a.ContentItems) || a.ContentItems.every(iter)); 
 
    }); 
 

 
console.log(result);

Смежные вопросы