skip to Main Content

Here I have created a function that will compile whether an object’s parentid matches its childId or not, so id 1 is a parent Id that has a child with 11,12, so if I call that function checkParentId(obj, 1, 12), that will return true, but here I have gotten the result false in the rest of the console statements, so how do I make the changes in that programme so that I will get the desired result? The program is given below.

const obj = [
        {
          id: 1,
          name: "parent 1",
          children: [
            {
              id: 11,
              name: "child 1",
              children: [
                {
                  id: 12,
                  name: "grand 1",
                  children: []
                }
              ]
            }
          ]
        },
        {
          id: 2,
          name: "parent 2",
          children: [
            {
              id: 21,
              name: "c1",
              children: []
            }
          ]
        },
      ];
      const checkParentId = (obj, parentId, childId) => {
    for (let item of obj) {
      if (item.id === parentId) {
        return true;
      }
      if (item.children.length > 0) {
        return checkParentId(item.children, parentId, childId);
      }
      return false;
    }
  };
      console.log(checkParentId(obj, 1, 12)); // true
      console.log(checkParentId(obj, 1, 21)); // false
      console.log(checkParentId(obj, 1, 11)); // true
      console.log(checkParentId(obj, 2, 21)); // true
      console.log(checkParentId(obj, 1, 2)); // false

2

Answers


  1. Currently, you are always searching the whole obj

    You want to search only within a particular entry inside obj. Therefore I think you need two functions.

    One function will find an person inside an array of people.

    The other function is your actual parent-child tester: it first finds the parent, and then looks within for the child.

    Calling an array obj is asking for trouble

    It makes it hard to keep track of what is a list of items, and what is an item.

    const parents = [ // This is an ARRAY, not an object
      {
        id: 1,
        children: [{
          id: 11,
          children: [{
            id: 12,
            children: [],
          }, ],
        }, ],
      },
      {
        id: 2,
        children: [{
          id: 21,
          children: [],
        }, ],
      },
    ];
    
    function findPersonInArray(people, id) { // Make clear that you are expecting an ARRAY of people
    
      let found = null
      people.forEach(person => { 
        if (person.id === id) {
          found = person;
        }
        if (person.children && person.children.length > 0) {
          const child = findPersonInArray(person.children, id);
          if (child) {
            found = child;
          }
        }
      })
      return found // This was one line too early in your code, stopping JS from looking in Person 2
    };
    
    function checkParentId(parents, parentId, childId) {
      const parent = findPersonInArray(parents, parentId);
      if (parent) {
        if (childId === parentId) { // Special case if parent and child are same
          return true;
        }
        if (findPersonInArray(parent.children, childId)) {
          return true;
        }
      }
      return false;
    }
    
    console.log(checkParentId(parents, 1, 12)); // true
    console.log(checkParentId(parents, 1, 21)); // false
    console.log(checkParentId(parents, 1, 11)); // true
    console.log(checkParentId(parents, 2, 21)); // true
    console.log(checkParentId(parents, 1, 2)); // false
    Login or Signup to reply.
  2. The problem is that when your code finds the parent node, it returns, but it should actually perform recursive searches below that node to find the child node.

    As you need to search for two nodes, it will be useful to first define a function that finds one node given an array of nodes to search into. Then you can use that function to first find the parent in the whole hierarchy, and then — when you have found the parent node — do a second search among the children of that found parent to find the child node. If all that succeeds, you can return true.

    Here is the code for that:

    const findNode = (nodes, id) => {
        for (const node of nodes) {
            const match = node.id === id ? node : findNode(node.children, id);
            if (match) return match;
        }
    };
    
    const checkParentId = (nodes, parentId, childId) => {
        const parent = findNode(nodes, parentId);
        return !!(parent && findNode(parent.children, childId));
    };
    
    // Your example & tests
    const obj = [{id: 1,name: "parent 1",children: [{id: 11,name: "child 1",children: [{id: 12,name: "grand 1",children: []}]}]},{id: 2,name: "parent 2",children: [{id: 21,name: "c1",children: []}]},];
          
    console.log(checkParentId(obj, 1, 12)); // true
    console.log(checkParentId(obj, 1, 21)); // false
    console.log(checkParentId(obj, 1, 11)); // true
    console.log(checkParentId(obj, 2, 21)); // true
    console.log(checkParentId(obj, 1, 2)); // false
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search