You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从嵌套对象中按指定类型提取link字符串数组

需求

从给定的嵌套对象中,根据指定类型提取对应的link字符串数组。

源对象
const obj = {
  id: '01',
  options: {},
  children: [
    {
      id: '02',
      type: 'green',
      options: {
        link: 'http://some-page-023'
      },
      children: [
        {
          id: '03',
          type: 'black',
          options: {},
          children: [],
        },
        {
          id: '04',
          type: 'green',
          options: {
            link: 'http://some-page-044'
          },
          children: [
            {
              id: '05',
              type: 'white',
              options: {},
              children: [],
            }
          ],
        }
      ],
    },
    {
      id: '06',
      type: 'black',
      options: {
        link: 'http://some-page-258'
      },
      children: [
        {
          id: '07',
          type: 'green',
          options: {
            link: 'http://some-page-055'
          },
          children: [],
        },
        {
          id: '08',
          type: 'white',
          options: {},
          children: [
            {
              id: '09',
              type: 'green',
              options: {
                link: 'http://some-page-023'
              },
              children: [],
            }
          ],
        }
      ],
    },
  ]
}
当前可正常运行的实现
const a = []

const getLinks = (data, ltype) => {
   if (data.children) {
     for( let el in data.children) {
       if (data.children[el].type === ltype) {
         a.push(data.children[el].options.link)
       }
       getLinks(data.children[el], ltype)
     }
   }
   return a
 }

 const result = getLinks(obj, 'green')
 console.dir(result, { depth: null })
运行结果

['http://some-page-023', 'http://some-page-044', 'http://some-page-055', 'http://some-page-023']

优化需求与问题尝试

需要优化实现,让数组在函数内部初始化并由函数直接返回。尝试的写法如下,但无法得到正确结果:

const getLinks = (data, ltype) => {
  const a = []
  function recursiveFind(children, ltype) {
    if (data.children) {
      for (let el in data.children) {
        if (data.children[el].type === ltype) {
          a.push(data.children[el].options.link)
        } else {
          recursiveFind(data.children[el], ltype)
        }
      }
    }
  }
  recursiveFind(data, ltype)
  return a
}

const result = getLinks(obj, 'green')
console.dir(result, { depth: null })
问题分析与正确优化实现

尝试的写法存在三个关键问题:

  1. 递归函数里错误引用外部的data.children,而非传入的参数,导致始终处理根节点的子元素,无法深入嵌套层级
  2. 使用else分支触发递归,会导致匹配类型的节点跳过子元素遍历,漏掉深层的匹配项
  3. for...in遍历数组语义不够清晰,更适合对象遍历

正确的优化实现如下:

const getLinks = (data, ltype) => {
  const links = [];
  
  function recursiveFind(node) {
    // 检查当前节点是否匹配类型,存在link则收集
    if (node.type === ltype && node.options?.link) {
      links.push(node.options.link);
    }
    // 递归处理所有子节点
    if (node.children?.length) {
      node.children.forEach(child => recursiveFind(child));
    }
  }
  
  recursiveFind(data);
  return links;
}

const result = getLinks(obj, 'green');
console.dir(result, { depth: null });

优化说明

  • 数组links在函数内部初始化,避免全局变量污染,多次调用函数不会互相干扰
  • 递归函数接收当前节点作为参数,正确遍历每一层级的元素
  • 先检查当前节点再递归子节点,不会遗漏任何匹配项
  • 使用可选链?.避免options或children不存在时抛出错误
  • 用forEach遍历数组,语义更贴合数组操作场景

运行后会得到和原实现一致的正确结果:

['http://some-page-023', 'http://some-page-044', 'http://some-page-055', 'http://some-page-023']

内容的提问来源于stack exchange,提问作者track_p54skate

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 04:30:51