[英]Recursively find all children from parent menu
我有一个像这样的JSON结构:
[
{"menuId":"1001","depth":"1","parentId":"0"},
{"menuId":"1002","depth":"1","parentId":"0"},
{"menuId":"1003","depth":"2","parentId":"1001"},
{"menuId":"1004","depth":"2","parentId":"1001"},
{"menuId":"1005","depth":"3","parentId":"1003"},
{"menuId":"1006","depth":"3","parentId":"1004"},
{"menuId":"1007","depth":"4","parentId":"1006"},
{"menuId":"1008","depth":"4","parentId":"1006"},
{"menuId":"1009","depth":"5","parentId":"1008"}
]
因此,我需要一个(可能)递归函数,该函数将找到一个menuId的所有子级,甚至包括深层嵌套的子级。
假设我要findChildrens('1004') 。 这应该返回以下结果:
['1006', '1007', '1008', '1009']
因为每个菜单都可以参考1004 。 不需要特定的订单。 深度可以不加限制地进行。
您可以通过检查parentId
并获取结果集的menuId
来采取迭代和递归的方法。 然后也添加新的子代。
function getChildren(array, id) { return array.reduce((r, { menuId, parentId }) => { if (parentId === id) { r.push(menuId, ...getChildren(array, menuId)); } return r; }, []); } var data = [{ menuId: "1001", depth: "1", parentId: "0" }, { menuId: "1002", depth: "1", parentId: "0" }, { menuId: "1003", depth: "2", parentId: "1001" }, { menuId: "1004", depth: "2", parentId: "1001" }, { menuId: "1005", depth: "3", parentId: "1003" }, { menuId: "1006", depth: "3", parentId: "1004" }, { menuId: "1007", depth: "4", parentId: "1006" }, { menuId: "1008", depth: "4", parentId: "1006" }, { menuId: "1009", depth: "5", parentId: "1008" }], result = getChildren(data, '1004'); console.log(result);
您可以像这样使用普通的递归。
var k = [{"menuId":"1001","depth":"1","parentId":"0"}, {"menuId":"1002","depth":"1","parentId":"0"}, {"menuId":"1003","depth":"2","parentId":"1001"}, {"menuId":"1004","depth":"2","parentId":"1001"}, {"menuId":"1005","depth":"3","parentId":"1003"}, {"menuId":"1006","depth":"3","parentId":"1004"}, {"menuId":"1007","depth":"4","parentId":"1006"}, {"menuId":"1008","depth":"4","parentId":"1006"}, {"menuId":"1009","depth":"5","parentId":"1008"}] var res = []; var findChildren = function(id){ k.forEach(obj => { if(obj.parentId === id){ res.push(obj.menuId); findChildren(obj.menuId) } }) } findChildren('1004'); console.log(res);
Array.prototype.map
和Array.prototype.filter
简单替代方法:
const data = [{"menuId":"1001","depth":"1","parentId":"0"},{"menuId":"1002","depth":"1","parentId":"0"},{"menuId":"1003","depth":"2","parentId":"1001"},{"menuId":"1004","depth":"2","parentId":"1001"},{"menuId":"1005","depth":"3","parentId":"1003"}, {"menuId":"1006","depth":"3","parentId":"1004"}, {"menuId":"1007","depth":"4","parentId":"1006"}, {"menuId":"1008","depth":"4","parentId":"1006"}, {"menuId":"1009","depth":"5","parentId":"1008"}]; function findChildren(id) { const menuIds = data.filter(({parentId}) => parentId == id).map(({menuId}) => menuId); return menuIds.concat(...menuIds.map(findChildren)); } console.log(findChildren(1004));
您可以使用使用递归函数的filter()
方法来查找子代。
ES6中的演示
const findChildrens = (data, menuId, oputArr, callback) => { let filterArr = data.filter(({ parentId }) => parentId == menuId); if (filterArr.length) { //Concat array with filtered data oputArr = [...oputArr, ...filterArr.map(({ menuId }) => menuId)]; //Recursive call for again search next node data findChildrens(data, oputArr[oputArr.length - 1], oputArr, callback); } else { //If find callback(oputArr); } } const arr =[{"menuId":"1001","depth":"1","parentId":"0"},{"menuId":"1002","depth":"1","parentId":"0"},{"menuId":"1003","depth":"2","parentId":"1001"},{"menuId":"1004","depth":"2","parentId":"1001"},{"menuId":"1005","depth":"3","parentId":"1003"},{"menuId":"1006","depth":"3","parentId":"1004"},{"menuId":"1007","depth":"4","parentId":"1006"},{"menuId":"1008","depth":"4","parentId":"1006"},{"menuId":"1009","depth":"5","parentId":"1008"}]; //Call find children function for 1004 findChildrens(arr, '1004', [], (res) => { console.log('result for 1004',res); }); //Call find children function 1001 findChildrens(arr, '1001', [], (res) => { console.log('result for 1001',res); });
.as-console-wrapper {max-height: 100% !important;top: 0;}
ES5中的演示
var filterArr = []; function findChildrens(data, menuId, oputArr, callback) { filterArr = data.filter(function(o) { return o.parentId == menuId; }); if (filterArr.length) { //Concat array with filtered data oputArr = [].concat.apply(oputArr, filterArr.map(function(o) { return o.menuId; })); //Recursive call for again search next node data findChildrens(data, oputArr[oputArr.length - 1], oputArr, callback); } else { //If find callback(oputArr); } } var arr = [{"menuId":"1001","depth":"1","parentId":"0"},{"menuId":"1002","depth":"1","parentId":"0"},{"menuId":"1003","depth":"2","parentId":"1001"},{"menuId":"1004","depth":"2","parentId":"1001"},{"menuId":"1005","depth":"3","parentId":"1003"},{"menuId":"1006","depth":"3","parentId":"1004"},{"menuId":"1007","depth":"4","parentId":"1006"},{"menuId":"1008","depth":"4","parentId":"1006"},{"menuId":"1009","depth":"5","parentId":"1008"}]; //Call find children function for 1004 findChildrens(arr, '1004', [], function(res){ console.log('result for 1004', res); }); //Call find children function 1001 findChildrens(arr, '1001', [], (res) => { console.log('result for 1001', res); });
.as-console-wrapper {max-height: 100% !important;top: 0;}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.