1

I've an array of nested objects. They represent a folder-like path or a menu with sub-navigation.

The structure is like it follows:

const MENU:Menu[] = [
  {
    value: 'Home',
    nested: [
      { value: 'home-1', url: 'home-1' },
      { value: 'home-2', url: 'home-2' },
    ],
  },

  {
    value: 'about',
    nested: [
      {
        value: 'about-1',
        url: 'about-1',
      },
      {
        value: 'about-2',
        url: 'about-2',
      },
    ],
  },
];

I want that for a given url to return the path using the value property.

For example, for home-1 => ['Home','home-1']

for about-2 => ['about','about-2']

The interface for this Menu is

interface Menu {
  value: string;
  nested?: Menu[];
  url?: string;
}

This is what I tried

function getPath(url, menu = MENU, navTreePath = []) {
  for (let i = 0; i < menu.length; i++) {
    const currentMenu = menu[i];

    if (currentMenu.url === url) {
      navTreePath.push(currentMenu.value);
      return navTreePath;
    } else if (currentMenu.nested) {
      navTreePath.push(currentMenu.value);
      return getNavTreePathFromUrl(url, currentMenu.nested, []);
    } else {
    }
  }
}

And the call

const path = getPath('about-2');

1 Answer 1

1

You would need recursive algorithm to crawl entire depth through:

const menu = [
  {
    value: 'Home',
    nested: [
      { value: 'home-1', url: 'home-1' },
      { value: 'home-2', url: 'home-2' },
    ],
  },

  {
    value: 'about',
    nested: [
      {
        value: 'about-1',
        url: 'about-1',
      },
      {
        value: 'about-2',
        url: 'about-2',
        nested: [
          {
            value: 'detailed about',
            url: 'detailedAbout'
          }
        ]
      },
    ],
  },
],
      
      getPath = (tree, needle, path=[]) => 
        tree.reduce((acc, {url, value, nested=[]}) => {
          if(url == needle){
            acc.push(...path, value)
          } else if (!!nested.length) {
            acc.push(...getPath(nested, needle, [...path, value]))
          }
          return acc
        }, [])

console.log(getPath(menu, 'detailedAbout'))
        
      

Sign up to request clarification or add additional context in comments.

5 Comments

Thank you. No need for that double !!. Right?
@GeorgianStan : Sorry, I didn't get the question. What did you mean by '..No need for that double' ?
**else if (!!nested.length) {} ** -here
@GeorgianStan : I just wasn't sure whether 0 will be casted smoothly to boolean in typescript environment (since I used plain JS), so it seemed to me a bit more safe
Yes it the same, Truthy and Falsy values are considered as well. Anyway it works. Thank you :)

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.