2013-04-18 9 views
5

Starałem się znaleźć/zbudować funkcję rekurencyjną, aby przetworzyć ten plik JSON i uzyskać całkowitą głębokość jego dzieci.Jak uzyskać całkowitą głębokość nieznanej hierarchii JSON?

Plik wygląda mniej więcej tak:

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

w jakiej formie chciałbyś, żeby wynik był? – minikomi

Odpowiedz

17

Można użyć funkcji rekurencyjnej, aby przejść przez cały drzewa:

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 
} 

Funkcja działa następująco:

  • Jeśli obiekt nie jest liściem (tj. Obiekt ma atrybut dzieci), to:
    • Oblicz głębokość każdego dziecka, z wyjątkiem maksymalnej jeden
    • powrót 1 + głębokość najgłębszego dziecka
  • W przeciwnym razie, powrót 1

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

EDIT Dzięki nowoczesnej obsłudze JavaScript funkcja może wyglądać następująco:

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

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

+0

Jak można tego użyć, aby uzyskać głębię dosłownie nieznanego JSON, lub aby można go było ponownie użyć do dowolnego rodzaju JSON? Zakładam, że wymaga to nazwania elementów JSON "dziećmi" i nie zadziała, jeśli np. Są. "samochody" zamiast "dzieci" lub gdy jeden JSON "lata", a drugi "ptaki". –

+0

const daje mi TypeError: Nie można dopasować do "undefined" lub "null". –

2

Będzie to policzyć "liśćmi" w drzewie:

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

oraz alternatywny sposób na głębokość:

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

Masz na myśli 'if (! Branch.children)'? –

+0

Tak, dobrze, dzięki! – minikomi

Powiązane problemy