Recursive tree search in a nested object structure in JavaScript

Your code is just missing a loop to inspect each child of a node in the child array. This recursive function will return the label property of a node or undefined if label not present in tree:

const search = (tree, target) => {
  if (tree.id === target) {
    return tree.label;
  }
  
  for (const child of tree.child) {
    const found = search(child, target);
    
    if (found) {
      return found;
    }
  }
};

const tree = {"id":1,"label":"A","child":[{"id":2,"label":"B","child":[{"id":5,"label":"E","child":[]},{"id":6,"label":"F","child":[]},{"id":7,"label":"G","child":[]}]},{"id":3,"label":"C","child":[]},{"id":4,"label":"D","child":[{"id":8,"label":"H","child":[]},{"id":9,"label":"I","child":[]}]}]};

console.log(search(tree, 1));
console.log(search(tree, 6));
console.log(search(tree, 99));

You can also do it iteratively with an explicit stack which won’t cause a stack overflow (but note that the shorthand stack.push(...curr.child); can overflow the argument size for some JS engines due to the spread syntax, so use an explicit loop or concat for massive child arrays):

const search = (tree, target) => {
  for (const stack = [tree]; stack.length;) {
    const curr = stack.pop();
    
    if (curr.id === target) {
      return curr.label;
    }

    stack.push(...curr.child);
  }
};

const tree = {"id":1,"label":"A","child":[{"id":2,"label":"B","child":[{"id":5,"label":"E","child":[]},{"id":6,"label":"F","child":[]},{"id":7,"label":"G","child":[]}]},{"id":3,"label":"C","child":[]},{"id":4,"label":"D","child":[{"id":8,"label":"H","child":[]},{"id":9,"label":"I","child":[]}]}]};

for (let i = 0; ++i < 12; console.log(search(tree, i)));

A somewhat more generic design would return the node itself and let the caller access the .label property if they want to, or use the object in some other manner.

Note that JSON is purely a string format for serialized (stringified, raw) data. Once you’ve deserialized JSON into a JavaScript object structure, as is here, it’s no longer JSON.

Leave a Comment