javascript - 如何在递归函数的循环中返回搜索到的 value?

给定以下作为节点树的对象数组

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: [],
  },
];

我需要通过其 id 获取这些对象之一

为此,下面的函数循环遍历每个节点,并将数据属性的 value 与搜索到的节点的 id 进行比较。

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 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 });

我已经确认,如果搜索 id 是列表的最后一个元素,它只会返回节点。在其他情况下,如示例所示,代码段返回 undefined

如何在递归函数的循环中返回搜索到的 value?

回答1

一个快速(当然也有点脏)的方法是检查 getNode 是否找到了 value:

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 });