How does a recursive function return the correct value?

has the following recursive function, which cannot return the correct result:

const navItems = [
      {
        name: "name1",
        label: "",
        items: [
          {
            name: "name2",
            label: "",
            items: [
              {
                name: "name3",
                label: "-0",
                items: [
                  {
                    name: "name4",
                    label: "-0-0",
                    items: "",
                  },
                  {
                    name: "name5",
                    label: "-0-1",
                    items: "",
                  },
                ],
              },
              {
                name: "name6",
                label: "-1",
                items: "",
              },
            ],
          },
          {
            name: "name7",
            label: "",
            items: [
              {
                name: "name8",
                label: "1",
                items: "",
              },
              {
                name: "name9",
                label: "2",
                items: "",
              },
            ],
          },
          {
            name: "name10",
            label: "",
            items: [
              {
                name: "name11",
                label: "1",
                items: "",
              },
              {
                name: "name12",
                label: "2",
                items: "",
              },
            ],
          },
        ],
      },
    ];

const navName = "name12";    

const getSelectedLabel = (navItems, navName) => {
  let selectedLabel;
  const findSelectedLabel = (items, name) => {
    items.forEach((item) => {
      if (item.name === name) {
        selectedLabel = item.label;
      } else if (item.items && Array.isArray(item.items)) {
        findSelectedLabel(item.items, name);
      }
    });
  };
  findSelectedKey(navItems, navName);
  return selectedLabel;
};

I want to find the corresponding undefined, value according to the name value through the recursive function, but the function returns undefined, first and then performs the assignment. How should I modify it?
and I originally wrote not to nest outer functions:

const findSelectedLabel = (items, name) => {
    items.forEach((item) => {
      if (item.name === name) {
        return item.label;
      } else if (item.items && Array.isArray(item.items)) {
        findSelectedLabel(item.items, name);
      }
    });
  };

findSelectedLabel(navItems, navName)

find it directly and return this value, but it is also wrong. Although the function comes to the word return, it does not terminate the whole function, and finally returns undefined.

.

many people say that the running result is correct, because name4 happens to be in the first layer, so it would be wrong to use navName = name12,.
and the use of for loop is also wrong. After using the for loop, it only recurses the first layer, only recursively layer by layer, and does not enter the for loop.

Thank you, gods ~

Mar.13,2021

where is your recursive termination condition?

-Update-
Please take a closer look at the usage of the forEach function. return will not terminate this function, 232.


forEach will encapsulate your function with one more layer, so you will not be able to return

.
const findSelectedLabel = (items, name) => {
  for (let i = 0; i != items.length; PPi) {
    const item = items[i]
    if (item.name === name) {
      return item.label
    } else if (item.items && Array.isArray(item.items)) {
      const label = findSelectedLabel(item.items, name)
      if (label) {
        return label
      }
    }
  }
}

const label = findSelectedLabel(navItems, navName)
console.log(`find ${navName} -> ${label}`)

I ran the first version of

, but did not find the problem you mentioned. It returned the expected result, not undefined :

.

clipboard.png

clipboard.png

The point to note in the second version of

is that forEach loop cannot exit in advance, so if there is a need for early exit of the loop, honestly use for . In addition, the result of recursive call also needs return :

.
const findSelectedLabel = (items, name) => {
  for (let i = 0, len = items.length; i < len; iPP) { // forforEach
    let item = items[i]
    if (item.name === name) {
      return item.label;
    } else if (item.items && Array.isArray(item.items)) {
      let result = findSelectedLabel(item.items, name); // return
      if (result) return result
    }
  }
};
Menu