遍历数组获取嵌套对象

Traverse through an Array to obtain nested object

我正在尝试遍历数组以获取嵌套在其中的特定对象。

有些对象包含一个children 属性,应该遍历直到找到匹配的对象。

这是一些示例数据,我正在尝试使用 id 作为 4

获取对象
const items = [{
    id: 1,
    title: 'Title for Item 1'
  },
  {
    id: 2,
    title: 'Title for Item 2',
    children: [
        { 
        id: 3,
        title: "Title for Item 3",
        children: [
            {
            id: 4,
            title: "Title for Item 4",
          }
        ]
      }
    ]
  },
]

我写了一些遍历代码但是它 returns undefined.

const items = [{
    id: 1,
    title: 'Title for Item 1'
  },
  {
    id: 2,
    title: 'Title for Item 2',
    children: [
        { 
        id: 3,
        title: "Title for Item 3",
        children: [
            {
            id: 4,
            title: "Title for Item 4",
          }
        ]
      }
    ]
  },
]

const getItem = (items) => {
  if (!items) return;
  const item = items && items.find(i => i.id === 4);
  if (!item) {
    items.forEach(i => {
      return getItem(i.children)
    })
    // This is where undefined is returned
  } else {
    console.log({
      item
    }) // Prints the correct object.
    return item;
  }
};


const s = getItem(items); // undefined

document.querySelector('#foo').textContent = s ? s : 'undefined';
<div id="foo"></div>

至少有两个问题可以解释为什么它不起作用:

  1. forEach 回调中的 return 语句将 return returned 值无处可去。没有任何反应。
  2. 没有检查递归调用的结果。需要检查它是否已定义。根据这一点,您可以决定是继续循环还是退出循环。

forEach 替换为 for...of 循环,这样你就可以 return "out of it",但只有当你有匹配时才这样做,否则你需要继续循环:

for (const item of items) {
    const match = getItem(item.children);
    if (match) return match;
}

请注意,在您的代码段中,您不应将 textContent 设置为 return 值,因为这是一个 object 并将转换为字符串“[Object object]”。例如,您可以只获取标题字符串并将其放入 textContent:

const items = [{
    id: 1,
    title: 'Title for Item 1'
  },
  {
    id: 2,
    title: 'Title for Item 2',
    children: [
        { 
        id: 3,
        title: "Title for Item 3",
        children: [
            {
            id: 4,
            title: "Title for Item 4",
          }
        ]
      }
    ]
  },
]

const getItem = (items) => {
  if (!items) return;
  const item = items && items.find(i => i.id === 4);
  if (!item) {
    for (const item of items) {
        const match = getItem(item.children);
        if (match) return match;
    }
  } else {
    console.log({
      item
    }) // Prints the correct object.
    return item;
  }
};


const s = getItem(items); // undefined

document.querySelector('#foo').textContent = s ? s.title : 'undefined';
<div id="foo"></div>