javascript查找深度嵌套的对象

javascript查找深度嵌套的对象,javascript,lodash,Javascript,Lodash,我需要使用javascript在对象的深度嵌套数组中递归地过滤对象,可能需要借助lodash。 如果我不知道数组中有多少嵌套对象,那么最干净的方法是什么 假设我有以下结构 [ { label: "first", id: 1, children: [] }, { label: "second", id: 2, children: [ { label: "third", id: 3,

我需要使用javascript在对象的深度嵌套数组中递归地过滤对象,可能需要借助lodash。 如果我不知道数组中有多少嵌套对象,那么最干净的方法是什么

假设我有以下结构

[
  {
    label: "first",
    id: 1,
    children: []
  },
  {
    label: "second",
    id: 2,
    children: [
      {
        label: "third",
        id: 3,
        children: [
          {
            label: "fifth",
            id: 5,
            children: []
          },
          {
            label: "sixth",
            id: 6,
            children: [
              {
                label: "seventh",
                id: 7,
                children: []
              }
            ]
          }
        ]
      },
      {
        label: "fourth",
        id: 4,
        children: []
      }
    ]
  }
];
我想找到id为6的,如果有子项,则返回true,否则返回false


当然,如果我有一个类似的数据结构,但项目数不同,它也应该可以工作。

也许一个类似的递归解决方案可能适合您?这里,通过提供的输入数据的“子节点”递归地搜索具有提供的id的节点。如果找到id匹配的子节点,将根据该节点
子节点
数组中存在的数据返回布尔结果:

函数nodeWithIdHasChildren(子节点,id){
for(const child of children){
//如果此子节点与提供的id匹配,则检查
//它的子数组中有数据,并相应地返回true/false
if(child.id==id){
if(Array.isArray(child.children)和&child.children.length>0){
返回真值
}
否则{
返回错误
}
}
否则{
const result=nodeWithIdHasChildren(child.children,id);
//如果此递归分支返回的结果不是未定义的
//然后从与提供的参数匹配的节点中假设它是true或false
//将返回结果向上传递到调用堆栈
如果(结果!==未定义){
返回结果
}
}
}  
}
常数数据=[
{
标签:“第一”,
id:1,
儿童:[]
},
{
标签:“第二”,
id:2,
儿童:[
{
标签:“第三”,
id:3,
儿童:[
{
标签:“第五”,
id:5,
儿童:[]
},
{
标签:“第六”,
id:6,
儿童:[
{
标签:“第七”,
id:7,
儿童:[]
}
]
}
]
},
{
标签:“第四”,
id:4,
儿童:[]
}
]
}
];
log('node 6有子节点:',nodeWithIdHasChildren(数据,6))
log('node 7有子节点:',nodeWithIdHasChildren(数据,7))
log('node 100有子节点:',nodeWithIdHasChildren(数据,7),'(因为node 100不存在)')
另外:

function explore(myArray, searchedId) {
    for (let i=0; i<myArray.length; i++) {
        let el;
        if (myArray[i].id == searchedId) {
            el = myArray[i];
        } else {
            el = explore(myArray[i].children, searchedId);
        }
        if (el) {
            return el.children.length > 0;
        }
    }
}    
函数探索(myArray,searchedId){
for(设i=0;i=0;
}
}
}    
您可以使用下面的“递归”检查
id
是否有子项

let arr=[{label:“first”,id:1,children:[]},{label:“second”,id:2,children:[{label:“third”,id:3,children:[{label:“fifth”,id:5,children:[]},{label:“seven”,id:7,children:[]}},{label:“fourren”,id:4,children:[]}];
函数hasChildren(arr,id){
设res=false
对于(以arr的d为单位){
如果(d.id==id)返回d.children.length>0
res=res | | hasChildren(d.children,id)
如果(res)返回true
}
返回res
}
log('ID4有子项?',有子项(arr,4))

console.log('ID6有子项?',hasChildren(arr,6))
由于您只需要一个
true
false
答案,您可以在递归中使用
some()
,有效地进行深度优先搜索,并使其非常简洁:

let arr=[{label:“first”,id:1,children:[]},{label:“second”,id:2,children:[{label:“third”,id:3,children:[{label:“fifth”,id:5,children:[]},{label:“seven”,id:7,children:[]}},{label:“fourren”,id:4,children:[]}];
函数findNested(arr,id){
let found=arr.find(node=>node.id==id)
返回发现
?发现.children.length>0
:arr.some((c)=>findNested(c.children,id))
} 
console.log(findNested(arr,6))//True:与子项一起找到
console.log(findNested(arr,7))//False:未找到子级

log(findNested(arr,97))//False:notfound
您可以使用三个简单的javascript函数完成此操作:

// Function to Flatten results
var flattenAll = function(data) {
  var result = [];
  var flatten = function(arr) {
    _.forEach(arr, function(a) {
      result.push(a);
      flatten(a.children);
    });
  };
  flatten(data);
  return result;  
};

// Function to search on flattened array
var search = function(flattened, id) {
  var found = _.find(flattened, function(d) { 
              return d.id == id;
            });
  return found;
};

// Function to check if element is found and have children
var hasChildren = function(element) {
  return element && element.children && element.children.length > 0;
}

// Usage, search for id = 6
hasChildren(search(flattenAll(your_data_object), 6))

这里有另一个解决方案,使用
递归
并仅通过一个
数组执行。查找

const data=[{label:“first”,id:1,children:[]},{label:“second”,id:2,children:[{label:“third”,id:3,children:[{label:“fifth”,id:5,children:[]},{label:“seven”,id:7,children:[]}},{label:“fourth”,id:4,children:[]}];
常量搜索=(数据,id)=>{
变量f,s=(d,id)=>d.find(x=>x.id==id?f=x:s(x.children,id))
s(数据、id)
返回f?f.childrence.length>0:false
}
console.log(search(data,6))//True:在子级中找到
console.log(search(data,7))//False:已找到但没有子级
console.log(search(data,15))//False:根本找不到
您可以使用a递归迭代节点,并简化检查存在性的逻辑,方法是:

const data=[{label:'first',id:1,children:[]},{label:'second',id:2,children:[{label:'third',id:3,children:[{label:'fifth',id:5,children:[]},{label:'sixten',id:6,children[{label:'seven:'seven',id:7,children[]}},{label:'fourren firth',id:4,children;
函数*节点(数组){
for(数组的常量节点){
屈服点;
产量*节点(节点.子节点);
}
}
const array=array.from(节点(数据));
log(array.some(node=>node.id==6&&node.children.length>0));
console.log(array.some(node=>node.id===7&&node.children.length>0));
或可用于检查所有值,并生成带有对节点的引用的平面id查找对象:
var lookup={},json='[{“label”:“first”,“id”:1,“children”:[]},{“label”:“second”,“id”:2,“children”:[{“label”:“third”,“id”:3,“children”:[{“label”:“fifth”,“id”:5,“children”:[]},{”
var id6HasChildren = _.filterDeep(obj,
  function(value, key, parent) {
    if (key == 'children' && parent.id == 6 && value.length) return true;
  },
  { leavesOnly: false }
).length>0;