0

I have tried to find a solution for my problem in the last two hours, which included trying myself, scanning lodash docs as well as SO for any suitable answer, but did not come up with anything remotely working or practical. I would be very grateful for help.

I have an object that can be any depth.

e.g.

{
  "name": "alpha",
  "children": [
    {
      "name": "beta",
      "children": [
        {
          "name": "gamma",
          "children": [
            {
              "name": "delta",
              "children": []
            }
          ]
        }
      ]
    },
    {
      "name": "epsilon",
      "children": [
        {
          "name": "zeta",
          "children": [
            {
              "name": "eta",
              "children": []
            }
          ]
        }
      ]
    }
  ]
}

I am looking for a function which will return the whole branch of this object where there is a matching name (if possible without lodash but if really needed its ok).

Given an input of 'gamma' I expect it to return


{
  "name": "alpha",
  "children": [
    {
      "name": "beta",
      "children": [
        {
          "name": "gamma",
          "children": [
            {
              "name": "delta",
              "children": []
            }
          ]
        }
      ]
    }
  ]
}

Given an input 't' I expect it to return the whole object, since it is included in the names of children in both branches.

2
  • Why 'a' input should return whole object? As object is having 'a' inside the name ? Commented May 29, 2021 at 15:35
  • @AkhilM because 'a' is included in the names of children both branches. So yes. So when entering 'z' it should only return the branch where 'zeta' occurs Commented May 29, 2021 at 15:37

2 Answers 2

1

You can separate this problem into two parts, first let's test if the name is present in the tree:

function hasStr(item, str) {
  return item.name.includes(str) || item.children.some(x => hasStr(x, str));
}

hasStr(item, 'gamma'); // true

You also asked to have a function that returns the passed object and return only a filtered version of the children:

function possibleAnswer(item, str) {
  return {
    name: item.name,
    children: item.children.filter(x => hasStr(x, str)),
  };
}

possibleAnswer(item, 'gamma'); // will return desired object
Sign up to request clarification or add additional context in comments.

Comments

-1

This problem can be solved with recursion as the depth is not know.

getNames = (nameChild, match) => {
     if (nameChild.length < 1) return false;

     if (nameChild.name.includes(match)) return true;

     k =  nameChild.children
                   .filter((child) => 
                         getNames(child, match)) 
     return (k.length > 0) ? k : false; 
}

suppose the object is assign to nameObj variable then

nameObj.children = getNames(nameObj, 'zeta');

this will do the work!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.