Home > Net >  How to identify if a value exists within a property of an object in a node tree?
How to identify if a value exists within a property of an object in a node tree?

Time:11-20

I need to check if the value of url exists within the path property in any of the objects or nodes of the following tree.

Regarding the tree. The children property is optional but if it exists it could be expanded indefinitely

The tree looks similar to the following

const items = [
  {
    path: "/admin/dashboard",
    menuIcon: {
      icon: "dashboard",
      title: "toolbar.dashboard",
    },
    // children: [
    //   {
    //     path: "/admin/collection",
    //     menuIcon: {
    //       icon: "summarize",
    //       title: "toolbar.reports",
    //     },
    //   },
    // ],
  },
  {
    path: "/admin/contents",
    menuIcon: {
      icon: "archive",
      title: "toolbar.contents",
    },
  },
  {
    path: "/admin/cigar-house-management",
    menuIcon: {
      icon: "home",
      title: "toolbar.directory-management",
    },
    children: [
      {
        path: "/admin/reports",
        menuIcon: {
          icon: "summarize",
          title: "toolbar.reports",
        },
        children: [
          {
            path: "/admin/admin-reports",
            menuIcon: {
              icon: "summarize",
              title: "toolbar.reports",
            },
          },
        ],
      },
    ],
  },
];

In order to achieve the desired result I am using the following function

function isValid(url, tree) {
  if (tree && Array.isArray(tree) && tree.length > 0) {
    for (const node of tree) {
      if (node.path === url) {
        return true;
      }

      if (!node.children) {
        continue;
      }

      const found = isValid(url, node.children);

      if (found) {
        return found;
      }

      return false;
    }
  }
}

Can be checked here

const url = "/admin/admin-reports";
const items = [
  {
    path: "/admin/dashboard",
    menuIcon: {
      icon: "dashboard",
      title: "toolbar.dashboard",
    },
    // children: [
    //   {
    //     path: "/admin/collection",
    //     menuIcon: {
    //       icon: "summarize",
    //       title: "toolbar.reports",
    //     },
    //   },
    // ],
  },
  {
    path: "/admin/contents",
    menuIcon: {
      icon: "archive",
      title: "toolbar.contents",
    },
  },
  {
    path: "/admin/cigar-house-management",
    menuIcon: {
      icon: "home",
      title: "toolbar.directory-management",
    },
    children: [
      {
        path: "/admin/reports",
        menuIcon: {
          icon: "summarize",
          title: "toolbar.reports",
        },
        children: [
          {
            path: "/admin/admin-reports",
            menuIcon: {
              icon: "summarize",
              title: "toolbar.reports",
            },
          },
        ],
      },
    ],
  },
];

function isValid(url, tree) {
  if (tree && Array.isArray(tree) && tree.length > 0) {
    for (const node of tree) {
      if (node.path === url) {
        return true;
      }

      if (!node.children) {
        continue;
      }

      const found = isValid(url, node.children);

      if (found) {
        return found;
      }

      return false;
    }
  }
}

const output = isValid(url, items);

console.log(output);

But I have noticed that when adding a new node (like the commented node in the tree example), for example as a child of the first node, it does not evaluate the ones after the parent node and likewise

I don't get along with recursion so I would appreciate your advice

Recursion is usually difficult for me so I would appreciate your advice.

Thanks in advance

CodePudding user response:

In your function, you're returning either true or false for every entry that either has a matching path, or has children. The only way to continue the iteration with your current code is to not match and not have children.

I'd recommend simplifying a bit so it's clearer:

function isValid(url, tree) {
  return tree.some(item =>
    item.path === url || (item.children && isValid(url, item.children))
  );
}
  • Related