Search code examples
javascriptrecursiondata-structureslogic

check childId match with parentId or not in js


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

Solution

  • 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