henrbu
henrbu

Reputation: 208

Trying to find element recursively in tree javascript

I'm trying to figure out how to search recursively element in json tree. For example I'm trying right now to reach 'Fruits' but can't figure out how to do it. Here's my json object

[
    {
        "_id": "604cab0acbdb8c1060698419",
        "name": "Grocery",
        "children": [
            {
                "children": [
                  {
                    "name": "Fruits",
                    "price": "200"
                    
                  }
                  ],
                "_id": "604cad9b4ae51310c6f313f6",
                "name": "Potatoes",
                "price": "200"
            },
            {
                "children": [],
                "_id": "604cae721257d510e679a467",
                "name": "Vegetables"
            }
        ],
        "date": "2021-03-13T12:07:38.186Z",
        "__v": 0
    } ]



function findName(name, tree) {
    if(tree.children.name == name {
        return tree;
    }

    if(tree.child == 0) {
        return
    }

    return findName(name, tree);
};

Upvotes: 1

Views: 870

Answers (2)

Shivam Singla
Shivam Singla

Reputation: 2201

const object = [
    {
        "_id": "604cab0acbdb8c1060698419",
        "name": "Grocery",
        "children": [
            {
                "children": [
                  {
                    "name": "Fruits",
                    "price": "200"
                    
                  }
                  ],
                "_id": "604cad9b4ae51310c6f313f6",
                "name": "Potatoes",
                "price": "200"
            },
            {
                "children": [],
                "_id": "604cae721257d510e679a467",
                "name": "Vegetables"
            }
        ],
        "date": "2021-03-13T12:07:38.186Z",
        "__v": 0
    } ]
  
function find(name, tree) {
  // tree is undefined, return `undefined` (base case)
  if (!tree) return

  if (Array.isArray(tree)) {
    // tree is an array
    // so iterate over every object in the array
    for (let i = 0; i < tree.length; i++) {
      const obj = tree[i]
      const result = find(name, obj)
      // `find` returned non-undefined value
      // means match is found, return it
      if (result) return result
      // no match found in `obj` so continue
    }
  } else if (tree.name === name) {
    // `tree` is a key-value object
    // and has matching `name` 
    return tree
  }

  // if no tree matching `name` found on the current `tree`
  // try finding on its `children`
  return find(name, tree.children)
}

console.log(find("Fruits", object))

Upvotes: 1

T.J. Crowder
T.J. Crowder

Reputation: 1075417

There are a couple of issues with your implementation.

  1. Your starting point is an array, but you treat it as though it were a node by trying to use its children property.
  2. You're looking for name on children, but children is an array.
  3. You're passing the same thing into findName at the end that you received. If you reach that point, you'll constantly call yourself until you run out of stack space.

Loop through the nodes in the array checking them and their children; see comments:

function findName(name, children) {
    if (Array.isArray(children)) {
        // Yes, check them
        for (const childNode of children) {
            if (childNode.name === name) {
                // Found it
                return childNode;
            }
            // Look in this node's children
            const found = findName(name, childNode.children);
            if (found) {
                // Found in this node's children
                return found;
            }
        }
    }
}

Live Example:

const tree = [
{
    "_id": "604cab0acbdb8c1060698419",
    "name": "Grocery",
    "children": [
        {
            "children": [
              {
                "name": "Fruits",
                "price": "200"
                
              }
              ],
            "_id": "604cad9b4ae51310c6f313f6",
            "name": "Potatoes",
            "price": "200"
        },
        {
            "children": [],
            "_id": "604cae721257d510e679a467",
            "name": "Vegetables"
        }
    ],
    "date": "2021-03-13T12:07:38.186Z",
    "__v": 0
} ];


function findName(name, children) {
    if (Array.isArray(children)) {
        // Yes, check them
        for (const childNode of children) {
            if (childNode.name === name) {
                // Found it
                return childNode;
            }
            // Look in this node's children
            const found = findName(name, childNode.children);
            if (found) {
                // Found in this node's children
                return found;
            }
        }
    }
}

console.log(findName("Fruits", tree));

Upvotes: 2

Related Questions