1

I have the following json:

{
"menu": [{

        "name": "vegetation",
        "id": "1",
        "children": [
            {
                "name": "landuse",
                "id": "1.1",
                "children": [
                    {
                        "name": "forest area",
                        "id": "1.1.1",
                        "children": null
                    }, 
                    {
                        "name": "plantation",
                        "id": "1.1.2",
                        "children": null
                    }
                ]
            }
        ]

}]
}

I want to dynamically access the objects whose value of "children" is null and store the "name" of these objects in a variable. For example in this case either forest area or plantation. How can I do this using javascript or jquery?

Salman
  • 393
  • 1
  • 7
  • 23
  • Can you elaborate on what you mean by *dynamically access* ? Do you mean regardless of nesting level? – Taplar Jul 27 '17 at 18:28

4 Answers4

0

You don't need jQuery for this, a simple for will do and, most likely, it's faster than anything else:

var childless = [], 
    checkForChildren = function(items){
      for (var i = 0; i < items.length; i++) {
        if (items[i].children) 
          checkForChildren(items[i].children);
        else 
          childless.push(items[i]);
      }
    };
 
// test it:
var menu = [{
    "name": "vegetation",
    "id": "1",
    "children": [{
      "name": "landuse",
      "id": "1.1",
      "children": [{
        "name": "forest area",
        "id": "1.1.1",
        "children": null
      },{
        "name": "plantation",
        "id": "1.1.2",
        "children": null
      }]
    }]
  }];

checkForChildren(menu);
console.log(childless);
tao
  • 82,996
  • 16
  • 114
  • 150
0

Recursion comes to mind.

var childless = [];
var recursive_function = function(obj){
  if(obj.children == null){
    childless.push(obj);
  } else {
    $.each(obj.children, function(child){
      recursive_function(child);
    }
  }
};
$.each(json_obj.menu, function(root_level){
  recursive_function(root_level);
});
console.log(childless);
console.log($.map(childless, function(x){return x.name;}));
0

var test = {
  "menu": [{

    "name": "vegetation",
    "id": "1",
    "children": [{
      "name": "landuse",
      "id": "1.1",
      "children": [{
          "name": "forest area",
          "id": "1.1.1",
          "children": null
        },
        {
          "name": "plantation",
          "id": "1.1.2",
          "children": null
        }
      ]
    }]

  }]
};

var hasNullChildren = [];

function checkChildren ( children ) {
  //loop over all children
  children.forEach(function(child){
    //if no children, add name to list
    if (!child.children) hasNullChildren.push(child.name);
    //check nested children
    else checkChildren(child.children);
  });
}

//start the recursion loop
checkChildren(test.menu);
console.log(hasNullChildren);
Taplar
  • 24,788
  • 4
  • 22
  • 35
  • Please note `Array.prototype.forEach()` is not supported in all current browsers. One should provide a [Polyfill](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach#Polyfill) for browsers that do not have it implemented. And, as a side note, it's so much slower than `for`. – tao Jul 27 '17 at 18:49
0

Recursively iterating through the array and searching for the children = null, gives the array with all the names of objects.

const obj = {
"menu": [{

        "name": "vegetation",
        "id": "1",
        "children": [
            {
                "name": "landuse",
                "id": "1.1",
                "children": [
                    {
                        "name": "forest area",
                        "id": "1.1.1",
                        "children": null
                    }, 
                    {
                        "name": "plantation",
                        "id": "1.1.2",
                        "children": null
                    }
                ]
            },{
                "name": "landuse",
                "id": "1.1",
                "children": null
            }
        ]

}]
}

function getNameWithNullChildren(arr) {
  let array = [];
  arr.forEach(item => {
    if(item.children === null) {
      array.push(item.name);
    } else {
      array = getNameWithNullChildren(item.children);
    }
  });
  return array;
}

console.log(getNameWithNullChildren(obj.menu));
Anurag Singh Bisht
  • 2,683
  • 4
  • 20
  • 26
  • Your solution is printing out Landuse in as well. Can you figure out why is that? – Salman Jul 27 '17 at 19:13
  • I have added one more object with `name as landuse` whose `children is null`, just to show that the solution is not static, it's dynamic and all object with `children = null` will be included in the array – Anurag Singh Bisht Jul 28 '17 at 06:05