2017-08-14 110 views
0

我想创建一个函数,它将遍历数组的层次并将它们连接在一起。我正在努力想办法做到这一点。Javascript递归函数问题

我调用一个Web API,它返回一些具有相同属性和布局的数据,但可以在有多少Hierarchy层数组中有所不同。

文件夹:文件夹可以包含“路线”,但也可以包含在其内部的另一个文件夹,然后可以还含有较多的“路线”等

路线:单个对象,它是一个路由。

例如:

{ 
    "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" 
     } 
    ] 
} 

我需要能够继续深入到层次结构和CONCAT所有文件夹数组的路线阵列,这样我就可以有一个孩子绑定剑道的TreeView这将是文件夹阵列。

到目前为止,我曾尝试:

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" 
     } 
    ] 
} 
+0

你或许应该更新与样品JSON和所需的输出你的问题,因此,很容易理解 –

+0

你有没有尝试过了吗?向我们展示您已拥有的代码,并询问您遇到麻烦的部分。 – DDRamone

+0

@DDRamone对不起,我添加了我迄今为止所拥有的内容。 –

回答

1

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);

+0

这是当你不知道它有多深时如何使用递归函数的例子。希望它会有所帮助 – DDRamone

+0

在您创建的routes数组中,似乎没有该文件夹(ID = 3的文件夹),它需要包含该路由数组中的所有文件夹。 –

+0

看更新后的答案 – DDRamone

0

从AB object删除property,你可以利用delete object.property

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

  • 创建modular功能 - formatData
  • 检查folders阵列具有任何数据或不
  • 如果folders阵列有数据显示,它调用formatData为每folder
  • 然后,检查为routes阵列。如果没有路由,返回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));

0

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

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; }