Reputation: 587
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
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
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
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
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