Wolfdog
Wolfdog

Reputation: 587

Recursively find all children from parent menu

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.

Upvotes: 3

Views: 2595

Answers (4)

Leonid Pyrlia
Leonid Pyrlia

Reputation: 1712

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

Upvotes: 1

Narendra Jadhav
Narendra Jadhav

Reputation: 10262

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

Upvotes: 0

sridhar..
sridhar..

Reputation: 2133

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

Upvotes: 4

Nina Scholz
Nina Scholz

Reputation: 386570

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

Upvotes: 4

Related Questions