2013-04-18 2 views
5

Я изо всех сил пытался найти/построить рекурсивную функцию для анализа этого файла JSON и получения полной глубины его детей.Как получить общую глубину неизвестной иерархии JSON?

файл выглядит примерно так:

var input = { 
    "name": "positive", 
    "children": [{ 
     "name": "product service", 
     "children": [{ 
      "name": "price", 
      "children": [{ 
       "name": "cost", 
       "size": 8 
      }] 
     }, { 
      "name": "quality", 
      "children": [{ 
       "name": "messaging", 
       "size": 4 
      }] 
     }] 
    }, { 
     "name": "customer service", 
     "children": [{ 
      "name": "Personnel", 
      "children": [{ 
       "name": "CEO", 
       "size": 7 
      }] 
     }] 
    }, { 
     "name": "product", 
     "children": [{ 
      "name": "Apple", 
      "children": [{ 
       "name": "iPhone 4", 
       "size": 10 
      }] 
     }] 
    }] 
} 
+0

В какой форме Вы хотите, чтобы результат был? – minikomi

ответ

17

Вы можете использовать рекурсивную функцию, чтобы пройти через все дерево:

getDepth = function (obj) { 
    var depth = 0; 
    if (obj.children) { 
     obj.children.forEach(function (d) { 
      var tmpDepth = getDepth(d) 
      if (tmpDepth > depth) { 
       depth = tmpDepth 
      } 
     }) 
    } 
    return 1 + depth 
} 

Функция работает следующим образом:

  • Если объект не является листом (т.е. объект имеет атрибут children), то:
    • Compute глубина каждого ребенка, сохранить максимальный один
    • возвращение 1 + глубина самого глубокого ребенка
  • В противном случае, возвращение 1

jsFiddle: http://jsfiddle.net/chrisJamesC/hFTN8/

EDIT С современным JavaScript функция может выглядеть так:

const getDepth = ({ children }) => 1 + 
    (children ? Math.max(...children.map(getDepth)) : 0) 

jsFiddle: http://jsfiddle.net/chrisJamesC/hFTN8/59/

+0

Как это можно использовать для получения глубины буквально неизвестного JSON или для его повторного использования для любого типа JSON? Я полагаю, это требует, чтобы элементы JSON назывались «детьми», и это не сработает, если они, например. «автомобили» вместо «детей», или когда один JSON «летает», а другой имеет «птиц». –

+0

const дает мне TypeError: не может совпадать с 'undefined' или 'null'. –

2

Это будет подсчитывать количество "листьев" в дереве:

var treeCount = function (branch) { 
    if (!branch.children) { 
     return 1; 
    } 
    return branch.children.reduce(function (c, b) { 
     return c + treeCount(b); 
    }, 0) 
} 

и альтернативный способ получить глубину:

var depthCount = function (branch) { 
    if (!branch.children) { 
     return 1; 
    } 
    return 1 + d3.max(branch.children.map(depthCount)); 
} 
+0

Вы имеете в виду 'if (! Branch.children)'? –

+0

Да, хорошо поймите спасибо! – minikomi

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