0

Given the following array of objects acting as a tree of nodes

const tree = [
  {
    label: "Gilfoyle",
    data: 160,
    children: [],
  },
  {
    label: "Nami",
    data: 171,
    children: [],
  },
  {
    label: "Root",
    data: 172,
    expanded: true,
    children: [
      {
        label: "Root child 1",
        data: 174,
        expanded: true,
        children: [
          {
            label: "Root child 2",
            data: 175,
            expanded: true,
            children: [
              {
                label: "Root child 3",
                data: 176,
                expanded: false,
                children: [{}],
              },
            ],
          },
        ],
      },
    ],
  },
  {
    label: "sk3wl 0f r00t",
    data: 159,
    children: [],
  },
  {
    label: "Collection",
    data: 166,
    children: [],
  },
  {
    label: "Compass",
    data: 165,
    children: [],
  },
  {
    label: "Sample",
    data: 17,
    children: [],
  },
  {
    label: "School of root",
    data: 18,
    children: [],
  },
];

I need to get one of these objects by its id

To this end, the following function loops through each node and compares the value of the data property with the id of the searched node.

function getNode(tree, id) {
  if (tree && Array.isArray(tree) && tree.length > 0) {
    for (const node of tree) {
      if (node.data === id) {
        console.dir(node, { depth: null });
        return node;
        break;
      }

      getNode(node.children, id);
    }
  }
}

The node is found as can be seen in the following snippet. But I require the function to return the node.

const tree = [
  {
    label: "Gilfoyle",
    data: 160,
    children: [],
  },
  {
    label: "Nami",
    data: 171,
    children: [],
  },
  {
    label: "Root",
    data: 172,
    expanded: true,
    children: [
      {
        label: "Root child 1",
        data: 174,
        expanded: true,
        children: [
          {
            label: "Root child 2",
            data: 175,
            expanded: true,
            children: [
              {
                label: "Root child 3",
                data: 176,
                expanded: false,
                children: [{}],
              },
            ],
          },
        ],
      },
    ],
  },
  {
    label: "sk3wl 0f r00t",
    data: 159,
    children: [],
  },
  {
    label: "Collection",
    data: 166,
    children: [],
  },
  {
    label: "Compass",
    data: 165,
    children: [],
  },
  {
    label: "Sample",
    data: 17,
    children: [],
  },
  {
    label: "School of root",
    data: 18,
    children: [],
  },
];

function getNode(tree, id) {
  if (tree && Array.isArray(tree) && tree.length > 0) {
    for (const node of tree) {
      if (node.data === id) {
        console.dir(node, { depth: null });
        return node;
        break;
      }

      getNode(node.children, id);
    }
  }
}

const output = getNode(tree, 176);

console.dir(output, { depth: null });

I have confirmed that it only returns the node if the search id is the last element of the list. In the other cases, as in the example, the snippet returns undefined

How can I return the searched value inside a loop in a recursive function?

1

1 Answer 1

1

A quick (and admittedly a little dirty) way is to just check if a value was found by getNode:

const tree = [
  {
    label: "Gilfoyle",
    data: 160,
    children: [],
  },
  {
    label: "Nami",
    data: 171,
    children: [],
  },
  {
    label: "Root",
    data: 172,
    expanded: true,
    children: [
      {
        label: "Root child 1",
        data: 174,
        expanded: true,
        children: [
          {
            label: "Root child 2",
            data: 175,
            expanded: true,
            children: [
              {
                label: "Root child 3",
                data: 176,
                expanded: false,
                children: [{}],
              },
            ],
          },
        ],
      },
    ],
  },
  {
    label: "sk3wl 0f r00t",
    data: 159,
    children: [],
  },
  {
    label: "Collection",
    data: 166,
    children: [],
  },
  {
    label: "Compass",
    data: 165,
    children: [],
  },
  {
    label: "Sample",
    data: 17,
    children: [],
  },
  {
    label: "School of root",
    data: 18,
    children: [],
  },
];

function getNode(tree, id) {
  if (tree && Array.isArray(tree) && tree.length > 0) {
    for (const node of tree) {
      if (node.data === id) {
        console.dir(node, { depth: null });
        return node;
        break;
      }

      const found = getNode(node.children, id);

      if (found) return found;
    }
  }
}

const output = getNode(tree, 176);

console.dir(output, { depth: null });

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

3 Comments

Works. Out of curiosity. Why do you think it's a little dirty solution?
It's not the cleanest. You should try to go for either a return statement at the end of the recursive function, or make the return statement the only statement in the body for the "cleanest" (but not always the best).
Makes sense. Thanks for the reply. Recursion is usually a mess for me. I appreciate the assistance

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.