user944513
user944513

Reputation: 12729

how to find object using recursion in javascript?

let tree = {
    name: "A",
    children: [
        {
            name: 'A-1',
            children: [
                {name: "A-1-A"},
                {name: "A-1-B"},
            ]
        },
        {
            name: 'B-1',
            children: [
                {
                    name: "B-1-A",
                    children: [
                        {name: "B-11-A"},
                        {name: "B-11-B"}
                    ]
                },
                {name: "B-1-B"},
            ]
        },

    ]


};

I am trying to find object from tree object using recursion .

when I call like this searchFn(tree,'A-1') it should return { name: 'A-1', children: [ {name: "A-1-A"}, {name: "A-1-B"}, ] } object

it I call like this searchFn(tree,'A-1-A') it should return this

{name: "A-1-A"}

I tried like this but not working

 function searchFn(obj ,searchText){
        if(obj.name === searchText) return obj
        if(obj.children.length > 0){
          return   searchFn(obj.children.pop(),searchText)
        }
      return null
    }

Upvotes: 4

Views: 91

Answers (5)

Alexandre Senges
Alexandre Senges

Reputation: 1579

First, you should create a class for readability. Then you should have a loop inside the function that iterates over the children and only returns if a child is found.

    class Node {
        static fromStruct = (struct) => {
            const tree = new Node(struct.name);
            if(!struct.children) return tree;
            for(const child of struct.children) {
                tree.children.push(Node.fromStruct(child));
            }
            return tree;
        }

        constructor(name){
            this.name = name;
            this.children = [];
        }
    
        addChild = (parentName, childName) => {
            const parent = this.searchFn(parentName);
            if(!parent) throw new Error("Parent not found");
            parent.children.push(new Node(childName));
        }
    
        searchFn = (name) => {
            if(this.name === name) return this;
            for(const child of this.children) {
                const found = child.searchFn(name);
                if(found !== null) return found;
            }
            return null;
        }
    }


    const data = {
        name: "A",
        children: [
            {
                name: 'A-1',
                children: [
                    {name: "A-1-A"},
                    {name: "A-1-B"},
                ]
            },
            {
                name: 'B-1',
                children: [
                    {
                        name: "B-1-A",
                        children: [
                            {name: "B-11-A"},
                            {name: "B-11-B"}
                        ]
                    },
                    {name: "B-1-B"},
                ]
            },
    
        ]
    };

    const tree = Node.fromStruct(data);
    console.log(tree.searchFn("A-1-A"));

Upvotes: 2

Param Siddharth
Param Siddharth

Reputation: 958

The problem with your function is that it only checks for the popped element from the array in the children property of the passed object, and not the other elements. Try this:

function searchFn(obj ,searchText) { 
    if(obj.name === searchText) return obj; 
    if(obj.children) {
        for (let x of obj.children) {
            let y = searchFn(x,searchText);
            if (y)
                return y;
        }
    }
    return null; 
}

Upvotes: 0

Code Maniac
Code Maniac

Reputation: 37757

You can try something like this

let tree = { name: "A", children: [{ name: 'A-1', children: [{ name: "A-1-A" }, { name: "A-1-B" }] }, { name: 'B-1', children: [{ name: "B-1-A", children: [{ name: "B-11-A" }, { name: "B-11-B" }] }, { name: "B-1-B" }] }] };

function searchFn(obj, text){
  if(obj.name === text) return obj
  else{
    if(obj && obj.children && Array.isArray(obj.children)){
      for(let value of obj.children){
        if(searchFn(value, text)){
          return searchFn(value, text)
        }
      }
    }
  }
  return null
}

console.log(searchFn(tree, 'A-1'))
console.log(searchFn(tree, 'A-1-A'))
console.log(searchFn(tree, 'A-A-A'))

Upvotes: 1

xdeepakv
xdeepakv

Reputation: 8125

const tree = {"name":"A","children":[{"name":"A-1","children":[{"name":"A-1-A"},{"name":"A-1-B"}]},{"name":"B-1","children":[{"name":"B-1-A","children":[{"name":"B-11-A"},{"name":"B-11-B"}]},{"name":"B-1-B"}]}]}

const searchFn = (tree, name) => {
  let result = null;
  if (typeof tree !== "object") return result;
  if (tree.name === name) return tree;
  if (tree.children && tree.children.length) {
    tree.children.some(data => (result = searchFn(data, name)));
  }
  return result;
};
console.log(searchFn(tree, "A-1-A"));
console.log(searchFn(tree, "A-1"));
console.log(searchFn(tree, ""));
.as-console-row {color: blue!important}

Upvotes: 1

Nina Scholz
Nina Scholz

Reputation: 386520

You need to iterate the children of the object and take a variable for the result.

function searchFn(object, searchText) {
    var result;
    if (object.name === searchText) return object;
    (object.children || []).some(o => result = searchFn(o, searchText));
    return result || null;
}


let tree = { name: "A", children: [{ name: 'A-1', children: [{ name: "A-1-A" }, { name: "A-1-B" }] }, { name: 'B-1', children: [{ name: "B-1-A", children: [{ name: "B-11-A" }, { name: "B-11-B" }] }, { name: "B-1-B" }] }] };

console.log(searchFn(tree, 'foo'));
console.log(searchFn(tree, 'A-1'));
.as-console-wrapper { max-height: 100% !important; top: 0; }

Upvotes: 4

Related Questions