Javascript 递归函数问题

Javascript recursive function issue

我正在尝试创建一个函数,它将遍历数组的层次结构并将它们连接在一起。我正在努力想办法做到这一点。

我将 Web API 称为 returns 我的一些数据,这些数据具有相同的属性和布局,但在层次结构层数组的数量方面可能有所不同。

文件夹:一个文件夹可以包含 'Routes',但也可以在其中包含另一个文件夹,后者还可以包含更多 'Routes' 等

路由:单个对象,即路由。

例如:

{
   "id":1,
   "folders":[
      {
         "id":2,
         "folders":[
            {
               "id":3,
               "folders":[],
               "routes":[]
            }
         ],
         "routes":[
            {
               "id":1002,
               "name":"Route3"
            },
            {
               "id":1003,
               "name":"Route4"
            }
         ]
      }
   ],
   "routes":[
      {
         "id":1000,
         "name":"Route1"
      },
      {
         "id":1001,
         "name":"Route2"
      }
   ]
}

我需要能够继续深入层次结构并将所有 Routes 数组与 Folders 数组连接起来,这样我就可以将 Kendo TreeView 与一个子项绑定,该子项将成为 Folders 数组.

到目前为止我已经尝试过:

for (var i = 0; i < Folders.length; i++) {
    if (Folder[i].Folders.length > 0) {
        for (var e = 0; e < Folder[i].Folder[e].length; e++) {
            if (Folder[i].Folders[e].length > 0) {
                ...
            }
        }
    }
}

这个方法的问题是我永远不知道会有多少层,因此不是一个可行的方法。

我需要的结果是上面的例子:

{
   "id":1,
   "folders":[
      {
         "id":2,
         "folders":[
            {
               "id":3,
               "folders":[

               ],
               "routes":[

               ]
            },
            {
               "id":1002,
               "name":"Route3"
            },
            {
               "id":1003,
               "name":"Route4"
            }
         ]
      },
      {
         "id":1000,
         "name":"Route1"
      },
      {
         "id":1001,
         "name":"Route2"
      }
   ]
}

var flatRoutes = function(folders){
  for(var i in folders){

    var cur = folders[i];
    if(cur.hasOwnProperty('folders')){
      flatRoutes(cur.folders);
    }
    
    if(cur.hasOwnProperty('routes')){
      for(var i in cur.routes){
        cur.folders.push(cur.routes[i]);
      }
      
      delete cur.routes;
    }
    
  }
  
  return folders;
}
  

var json = {
   "id":1,
   "folders":[
      {
         "id":2,
         "folders":[
            {
               "id":3,
               "folders":[],
               "routes":[]
            }
         ],
         "routes":[
            {
               "id":1002,
               "name":"Route3"
            },
            {
               "id":1003,
               "name":"Route4"
            }
         ]
      }
   ],
   "routes":[
      {
         "id":1000,
         "name":"Route1"
      },
      {
         "id":1001,
         "name":"Route2"
      }
   ]
}


var routes = flatRoutes([json]);

console.log(routes);

要从 ab object 中删除 property,您可以使用 delete object.property.

我已经采取了以下步骤,我认为它给出了正确的结果。

  • 创建一个 modular 函数 - formatData
  • 检查folders数组是否有数据
  • 如果folders数组有数据,为其中的每个folder调用formatData
  • 然后,检查 routes 数组。如果没有路由,return data
  • 如果 routes 数组有数据,只需将每个 route 推入文件夹数组和 remove 来自对象的 routes 属性。

let data = {
  "id": 1,
  "folders": [{
    "id": 2,
    "folders": [{
      "id": 3,
      "folders": [],
      "routes": []
    }],
    "routes": [{
        "id": 1002,
        "name": "Route3"
      },
      {
        "id": 1003,
        "name": "Route4"
      }
    ]
  }],
  "routes": [{
      "id": 1000,
      "name": "Route1"
    },
    {
      "id": 1001,
      "name": "Route2"
    }
  ]
};

function formatData(data) {
  if (data.folders.length) {
    data.folders.forEach(folder => {
        return formatData(folder);
    });
  } 
  if (data.routes.length) {
    data.routes.forEach(route => {
      data.folders.push(route);
    });
    delete data.routes;
  }
  return data;
}

console.log(formatData(data));

您可以使用迭代和递归方法。

var data = { id: 1, folders: [{ id: 2, folders: [{ id: 3, folders: [], routes: [] }], routes: [{ id: 1002, name: "Route3" }, { id: 1003, name: "Route4" }] }], routes: [{ id: 1000, name: "Route1" }, { id: 1001, name: "Route2" }] },
    result = [data].map(function iter(o) {
        return {
            id: o.id,
            folders: (o.folders && o.folders.map(iter) || []).concat(o.routes || [])
        };
    })[0];

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }