0

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);
};
henrbu
  • 137
  • 10
  • JSON is a *textual notation* for data exchange. [(More here.)](http://stackoverflow.com/a/2904181/157247) If you're dealing with JavaScript source code, and not dealing with a *string*, you're not dealing with JSON. – T.J. Crowder Mar 13 '21 at 13:22
  • 1
    `tree.children` is an array. Arrays don't have `name` properties. You have to [loop through](https://stackoverflow.com/questions/9329446/for-each-over-an-array-in-javascript) the objects in the array (or use the built-in `find` method). – T.J. Crowder Mar 13 '21 at 13:23
  • @T.J.Crowder What if children is nested n times, will it be still found? – henrbu Mar 13 '21 at 13:26
  • Yes, if you call `findName` with the objects in the array. – T.J. Crowder Mar 13 '21 at 13:29
  • Hmmm.. I will try your solution even it sounds confusing little bit. – henrbu Mar 13 '21 at 13:33

2 Answers2

1

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));
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
1

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))
Shivam Singla
  • 2,117
  • 1
  • 10
  • 22