如何从嵌套对象中获取字符串数组

How to get array of strings from nested object

提问人:track_p54skate 提问时间:11/21/2022 最后编辑:track_p54skate 更新时间:11/21/2022 访问量:76

问:

如何从嵌套对象中获取字符串数组

根据类型,需要获取“链接”数组 源对象:

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 })
JavaScript 数组 对象 递归 嵌套

评论

0赞 Nina Scholz 11/21/2022
如果对结果使用全局变量,为什么是函数?

答:

2赞 Nina Scholz 11/21/2022 #1

您可以直接检查对象并获取链接并获取嵌套结构的平面数组。

const
    getLinks = (object, ltype) => {
        const links = [];
        if (object.type === ltype) links.push(object.options.link);
        links.push(...object.children.flatMap(o => getLinks(o, ltype)));
        return links;
    },
    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: [] }] }] }] },
    result = getLinks(obj, 'green');

console.dir(result);

一种略有不同的方法,对想要的类型进行了闭合。

const
    getLinks = (data, ltype) => {
        const
            gl = ({ type, options: { link }, children }) => [
                ...(type === ltype ? [link] : []),
                ...children.flatMap(gl)
            ];
        return gl(data);
    },
    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: [] }] }] }] },
    result = getLinks(obj, 'green');

console.dir(result);

评论

0赞 gog 11/21/2022
这些只是移动大量数据,没有任何明显的意义。...
0赞 track_p54skate 11/21/2022
如果不使用 flatMap(),@NinaScholz?
1赞 gog 11/21/2022 #2

你的第二个片段实际上很好,你只是把参数弄错了:

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

还要注意,它比 。for..offor..in

或者,您可以摆脱临时数组并使用生成器:

function *getLinks (data, ltype) {
    if (data.children) {
        for (let c of data.children) {
            if (c.type === ltype)
                yield c.options.link
            yield *getLinks(c, ltype)
        }
    }
}

result = [...getLinks(obj, 'green')]