如何在javascript中编写递归平面地图?

Dim*_*iwa 7 javascript recursion

我有一个嵌套路由的对象.

任何路线都可以包含路线列表childRoutes.

我想获得包含密钥的所有路由的列表menu.

const routes = [{
        "name": "userManagement",
        "childRoutes": [
          {
            "name": "blogManagement",
            "childRoutes": [
              {
                "name": "blog",  // <=== I want to have this route
                "menu": {
                  "role": 1020
                }
              }
            ],
          },
          {
            "name": "organizationList", // <=== and this one
            "menu": {
              "role": 1004
            }
          }

        ],
      }, { 
      	"name": "test", 
  	"menu": { "role": 4667 }
  	}];

const deepFlatten = arr => [].concat(...arr.map(v => (Array.isArray(v) ? deepFlatten(v) : v)));

// Should handle nesting of route 
const links = deepFlatten(routes).filter((r) => !!r.menu); 

console.log('it should have a length of 3:', links.length === 3);
console.log('it should be blog:', links[0].name === 'blog');
console.log('it should be organizationList:', links[1].name === 'organizationList');
console.log('it should be test:', links[2].name === 'test');
Run Code Online (Sandbox Code Playgroud)

上面的代码段不能递归地工作.

如何在没有任何第三方库的情况下递归执行此操作?

Tha*_*you 8

@yBrodsky 的答案可以flatMap在这里进行调整,以隔离和展示通用操作 \xe2\x80\x93 ,您将看到路线因程序员的大部分管道而reduce扁平map化。concat

\n\n

\r\n
\r\n
// polyfill if you don\'t have it\r\nArray.prototype.flatMap = function (f)\r\n{\r\n  return this.reduce ((acc, x) =>\r\n    acc.concat (f (x)), [])\r\n}\r\n\r\n// your data   \r\nconst routes =\r\n    [ { name : "userManagement"\r\n      , childRoutes :\r\n            [ { name : "blogManagement"\r\n              , childRoutes :\r\n                    [ { name : "blog"\r\n                      , menu : { role : 1020 }\r\n                      }\r\n                    ]\r\n              }\r\n            , { name : "organizationList"\r\n              , menu : { role : 1004 }\r\n              }\r\n            ]\r\n      }\r\n    , { name : "test"\r\n      , menu : { role : 4667 }\r\n      }\r\n    ]\r\n\r\n// flat-mapped routes\r\nconst allChildRoutes =\r\n  routes.flatMap (function loop (node) {\r\n    if (node.childRoutes)\r\n      return node.childRoutes.flatMap (loop)\r\n    else\r\n      return [node]\r\n  })     \r\n  \r\nconsole.log (allChildRoutes)
Run Code Online (Sandbox Code Playgroud)\r\n
\r\n
\r\n

\n


yBr*_*sky 5

这个怎么样,好像行得通。

const flatten = (routes) => {
    return routes.reduce((acc, r) => {
      if(r.childRoutes && r.childRoutes.length) {
        acc = acc.concat(flatten(r.childRoutes));
      } else {
        acc.push(r);
      }

      return acc;
    }, [])
}
Run Code Online (Sandbox Code Playgroud)

https://jsfiddle.net/vv9odcxw/