【问题标题】:Flat array to deep nested object array平面数组到深层嵌套对象数组
【发布时间】:2018-11-29 22:05:21
【问题描述】:

我正在尝试采用平坦的路径数组,并创建嵌套的对象数组。我遇到的麻烦是生成子节点的递归部分......

起始数组:

const paths = [ 
  '/',
  '/blog',
  '/blog/filename',
  '/blog/slug',
  '/blog/title',
  '/website',
  '/website/deploy',
  '/website/infrastructure',
  '/website/infrastructure/aws-notes',
];

具有所需的输出结构:

[
  { 
    path: '/',
  },
  {
    path: '/blog',
    children: [
      {
        path: '/blog/filename',
      },
      {
        path: '/blog/slug',
      },
      {
        path: '/blog/title',
      }
    ]
  },
  { 
    path: '/website',
    children: [
      {
        path: '/website/deploy',
      },
      {
        path: '/website/infrastructure',
        children: [
          {
            path: '/website/infrastructure/aws-notes',
          }
        ],
      },
    ],
  },
]

这是我目前所处的位置,我尝试了一些东西,但最终以无限循环或糟糕的结构结束:

const getPathParts = (path) => path.substring(1).split('/');
const getPathLevel = (path) => getPathParts(path).length - 1;
const getTree = (paths) => paths.reduce((tree, path, i, paths) => {
  const pathParts = getPathParts(path);
  const pathDepth = getPathLevel(path);
  const current = pathParts[pathDepth];
  const parent = pathParts[pathDepth - 1] || null;
  const item = {
    path,
    children: [],
  };

  if (pathDepth > 0 || parent !== null) {
    // recursive check for parent, push this as a child to that parent?
    return [...tree];
  }

  return  [
    ...tree, 
    item,
  ];
}, []);

我已经尝试array.find|some|filter 来检索父节点,但我不知道如何将节点作为子节点推送到正确的嵌套节点中。注意:我已经为示例提取了一些代码,请原谅任何语法/拼写问题。

【问题讨论】:

    标签: javascript arrays recursion ecmascript-6


    【解决方案1】:

    您可以通过获取路径并拆分它们并检查具有路径的对象是否已经存在来采用嵌套方法。如果不推送一个新对象。

    稍后返回实际对象的子对象。继续,直到没有更多可用的路径项。

    const
        paths = ['/', '/blog', '/blog/filename', '/blog/slug', '/blog/title', '/website', '/website/deploy', '/website/infrastructure', '/website/infrastructure/aws-notes'],
        result = paths.reduce((r, path) => {
            path.split(/(?=\/)/).reduce((a, _, i, p) => {
                var temp = a.find(o => o.path === p.slice(0, i + 1).join(''));
                if (!temp) {
                    a.push(temp = { path, children: [] });
                }
                return temp.children;
            }, r);
            return r;
        }, []);
    
    console.log(result);
    .as-console-wrapper { max-height: 100% !important; top: 0; }

    对于仅使用最终目录的路径进行创建,您可以使用部分路径进行创建。

    这种方法可以防止空子数组。

    const
        paths = [
            '/',
            '/blog/filename',
            '/blog/slug',
            '/blog/title',
            '/website/deploy',
            '/website/infrastructure/aws-notes'
        ],
        result = [];
    
    paths.reduce((r, string) => {
        string.split(/(?=\/)/).reduce((o, _, i, p) => {
            o.children = o.children || [];
            var path = p.slice(0, i + 1).join(''),
                temp = o.children.find(o => o.path === path);
            if (!temp) {
                o.children.push(temp = { path });
            }
            return temp;
        }, r);
        return r;
    }, { children: result });
    
    console.log(result);
    .as-console-wrapper { max-height: 100% !important; top: 0; }

    【讨论】:

    • @gordie,对不起。请提出一个新问题。
    猜你喜欢
    • 2019-02-17
    • 2020-12-15
    • 2016-05-18
    • 1970-01-01
    • 1970-01-01
    • 2020-04-13
    • 2020-07-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多