1

this is my json file:

{
  "categories": {

    "category": [
      {
        "id": "1",
        "title": "Android",
    "subcategory": [

        {
            "id": "1",
            "title": "JavaScript",
            "question": [

My question is: if subcategory element can appear infinite number of times as nested in itself how can I get all the elements of every subcategory in my json file to be displayed with the help of javascript?, how can i get dipper in the nesting? if i'm writing my code:

data.categories.category[i].subcategory[0].subcategory[0].subcategory[0].title          

that means that I need to add subcategory[0] infinite number of times to get to each title attribute - creating a lot of different functions to handle every different situation - and this is my problem.

nnnnnn
  • 147,572
  • 30
  • 200
  • 241
Avi A
  • 69
  • 8
  • 4
    What do you mean by infinite ? An unspecified number of times ? – Denys Séguret May 16 '13 at 13:12
  • 6
    Use [recursion](http://en.wikipedia.org/wiki/Recursion_(computer_science)#Recursive_procedures) – Quentin May 16 '13 at 13:12
  • Followup on @Quentin's comment: use [recursion](http://stackoverflow.com/questions/16588418/infinite-nested-elements-in-a-json-file-how-to-get-specific-element#comment23840284_16588418) – tckmn May 16 '13 at 13:13
  • you will brek the interwebz with your infinite json! But perhaps this question will help you: http://stackoverflow.com/a/16561031/1047823 – Christoph May 16 '13 at 13:19

2 Answers2

2

Use a recursive function. Something like:

function getLeafCategory(node) {
    if (node.subcategory && node.subcategory[0]) {
        return getLeafCategory(node.subcategory[0]);
    }
    return node;
}

Obviously this won't work if your JSON really is infinite! But in that case you wouldn't have been able to load it in the first place!

You'd call it something like this:

var myTitle = getLeafCategory(data.categories.category[i]).title;

What the function will do is it will examine what you passed in and see if it has a subcategory and if that subcategory has a zeroth entry. If it does, it passes that new node to the function again. If not, then you've reach the end of the chain and it returns your result.

A couple of notes on recursion: If your chain is really long, you may eventually get a Stack Overflow. It should be possible to rewrite the recursive function as a while loop, but the code is (IMHO) a little less elegant.

function getLeafCategoryWithoutRecursion(node) {
    while(node.subcategory && node.subcategory[0]) {
        node = node.subcategory[0]
    }
    return node;
}

Also note both of these functions are assuming that you don't have any loops (where a subcategory actually points back to a parent) which will cause both of these functions to hang in an infinite loop (although the recursive one will eventually throw a Stack Overflow).

Matt Burland
  • 44,552
  • 18
  • 99
  • 171
2

Just iterate them:

function getAllTitles(node) {
    var cats = data.categories.category,
        titles = [];
    for (var i=0; i<cats.length; i++) {
        var cat = cats[i];
        while (cat.subcategory && cat.subcategory[0])
            cat = cat.subcategory[0]; // travel deeper
        // now cat is a subcategory that has no subcategories any more
        titles.push(cat.title);
    }
    return titles;
}
Bergi
  • 630,263
  • 148
  • 957
  • 1,375