最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Recursively find all children from parent menu - Stack Overflow

programmeradmin10浏览0评论

I have a JSON structure like this:

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

So I need a (probably) recursive function, that will find all children of one menuId, even the deep nested ones.

So let's say I wanna findChildrens('1004'). This should return the following result:

['1006', '1007', '1008', '1009']

because each of this menus can be referenced back to 1004. No specific order is required. The depth can go indefnitly.

I have a JSON structure like this:

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

So I need a (probably) recursive function, that will find all children of one menuId, even the deep nested ones.

So let's say I wanna findChildrens('1004'). This should return the following result:

['1006', '1007', '1008', '1009']

because each of this menus can be referenced back to 1004. No specific order is required. The depth can go indefnitly.

Share Improve this question edited Aug 27, 2018 at 13:37 guntbert 5366 silver badges19 bronze badges asked Aug 27, 2018 at 12:02 WolfdogWolfdog 5871 gold badge11 silver badges20 bronze badges 3
  • 3 nice idea, what have you tried? – Nina Scholz Commented Aug 27, 2018 at 12:03
  • Technically they are not children of id 1004, are they ? – pixlboy Commented Aug 27, 2018 at 12:05
  • gist.github./shakhal/3cf5402fc61484d58c8d – Hyyan Abo Fakher Commented Aug 27, 2018 at 12:05
Add a ment  | 

4 Answers 4

Reset to default 4

You could take an iterative and recursive approach by checking the parentId and get the menuId for the result set. Then add the new children as well.

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

You can just use normal recursion like this.

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

A simple and short alternative with Array.prototype.map and 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));

You could use filter() method of using recursive function to find children.

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

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

发布评论

评论列表(0)

  1. 暂无评论