Javascript 如何创建一个函数来检索所有子项';来自嵌套对象的id
我想检索特定组的所有子ID,这些子ID可以是深度嵌套的,也可以不是 下面是一个json示例:Javascript 如何创建一个函数来检索所有子项';来自嵌套对象的id,javascript,arrays,iteration,children,Javascript,Arrays,Iteration,Children,我想检索特定组的所有子ID,这些子ID可以是深度嵌套的,也可以不是 下面是一个json示例: [ { id: 1, name: 'Desjardins Group 1', children: [ { id: 2, name: 'Analysts', children: [] }, { id: 3, name: 'Administration', children: [] } ]
[
{
id: 1,
name: 'Desjardins Group 1',
children: [
{ id: 2, name: 'Analysts', children: [] },
{ id: 3, name: 'Administration', children: [] }
]
},
{
id: 4,
name: 'Desjardins Group 2',
children: [
{ id: 5, name: 'Consultants1', children: [] },
{
id: 6,
name: 'Consultant2',
children: [
{
id: 7, name: 'Interns', children: [
{ id: 8, name: 'subInterns1', children: [] },
{ id: 9, name: 'subInterns2', children: [] },
{ id: 10, name: 'subInterns3', children: [] }
]
}
]
}
]
}
]
我试图使一个接受id的函数有一个参数,并返回所有子id。
例如:getChildGroups(6)将返回7、8、9和10
我想递归函数和过滤器是最好的选择,但我找不到合适的例子。将问题分为两个较小的问题可能是个好主意:
function findGroupId(o, id) {
if (o.id == id) {
// We found it!
return o;
}
if (Array.isArray(o)) {
// If we start with a list of objects, pretend it is the root node
o = {children: o}
}
let results = [];
for (let c of o.children) {
// recursively call this function again
results.push(findGroupId(c, id))
}
// return the first matching node
return results.filter(r => r !== undefined)[0];
}
至于第二个问题:
function getAllChildrenIDs(o) {
if (o.children === undefined)
return [];
let ids = [];
for (c of o.children) {
ids.push(c.id);
// recursively call this function again
for (id of getAllChildrenIDs(c))
ids.push(id);
}
return ids;
}
如果我们把这些放在一起:
让示例=[{
id:1,
名称:“Desjardins组1”,
儿童:[{
id:2,
名称:"分析员",,
儿童:[]
},
{
id:3,
名称:'管理',
儿童:[]
}
]
},
{
id:4,
名称:“Desjardins组2”,
儿童:[{
id:5,
名称:“顾问1”,
儿童:[]
},
{
id:6,
姓名:“顾问2”,
儿童:[{
id:7,
姓名:'实习生',
儿童:[{
id:8,
名称:'sub1',
儿童:[]
},
{
id:9,
名称:'sub2',
儿童:[]
},
{
id:10,
名称:'sub3',
儿童:[]
}
]
}]
}
]
}
];
函数findGroupId(o,id){
如果(o.id==id){
返回o;
}
if(数组isArray(o)){
o={
儿童:o
}
}
让结果=[];
对于(让c of o.儿童){
结果.推送(findGroupId(c,id))
}
返回结果。筛选器(r=>r!==未定义)[0];
}
函数getAllChildrenIDs(o){
if(o.children==未定义)
返回[];
设ids=[];
适用于(o.c.儿童){
id.push(c.id);
for(GetAllChildrenID的id(c))
id.push(id);
}
返回ID;
}
log(getAllChildrenId(findGroupId(示例6))
以下是Johann Bauer答案的简化版本
第一个函数只查找与给定ID匹配的第一个节点,无需任何数据累积:
function findNode(data, id) {
if (!Array.isArray(data)) return;
for (let entry of data) {
if (entry.id === id) {
return entry;
} else {
const node = findNode(entry.children, id);
if (node) {
return node;
}
}
}
}
第二个函数只获取子ID,将它们存储在传递的数组中,而不创建任何中间数组:
function getChildIds(node, result = []) {
if (!node) return;
if (!Array.isArray(node.children)) return;
for (let entry of node.children) {
result.push(entry.id);
getChildIds(entry, result);
}
return result;
}
为了让我们帮助您,您必须与我们分享您已经尝试过的内容。我认为您的第一个函数是不必要的复杂-它只需要递归,直到找到所需的ID,然后停止。不需要累积任何类型的结果数组。如果第二个函数累积到一个传递的数组中,而不是在递归的每个阶段创建一个新的数组,那么它可能也会更好。@AInitak我最初考虑的结构是不同的元素共享相同的ID,但为了简单起见,没有考虑这个结构。你的版本要优雅得多。