我有一个数组,其中包含深度未知的对象,像这样
var objects = [{
id: 1,
name: 'foo'
}, {
id: 2,
name: 'bar',
childs: [{
id: 3,
name: 'baz',
childs: [{
id: 4,
name: 'foobar'
}]
}]
}];
我希望能够通过其ID过滤特定的子对象。
当前,我正在使用这个小lodash脚本(从this question引用),但是它仅适用于不深于一层的对象。因此,搜索id: 1
和id: 2
会很好,而搜索id: 3
或id: 4
会返回undefined。
function deepFilter(obj, search) {
return _(obj)
.thru(function(coll) {
return _.union(coll, _.map(coll, 'children'));
})
.flatten()
.find(search);
}
答案 0 :(得分:2)
您需要递归调用该函数才能定位子对象。尝试关注
遍历数组,并为每个对象检查是否找到id
。如果是,则中断并返回结果,否则继续在child
(如果存在)中进行搜索。
方法1:遍历树枝
使用这种方法,代码首先遍历第一个元素,直到最后一个孩子,然后遍历第二个元素,最后一个孩子,依此类推。
var objects = [{id: 1,name: 'foo'}, {id: 2,name: 'bar',childs: [{id: 3,name: 'baz',childs: [{id: 4,name: 'foobar'}]}]}];
function findObject(arr, id) {
var result;
for (let i = 0 ; i < arr.length; i++) {
if(arr[i].id === id) {
result = arr[i];
break;
}
if(arr[i].childs) {
result = findObject(arr[i].childs, id);
if(result) break;
}
}
return result;
}
console.log(findObject(objects, 4));
方法2:按深度遍历树的深度
使用这种方法,首先遍历第一级元素,然后遍历第二级元素,依此类推。
var objects = [{id: 1,name: 'foo'}, {id: 2,name: 'bar',childs: [{id: 3,name: 'baz',childs: [{id: 4,name: 'foobar'}]}]}];
function findObject(arr, id) {
var result;
var children = [];
for (let i = 0 ; i < arr.length; i++) {
if(arr[i].id === id) {
result = arr[i];
break;
}
if(arr[i].childs) {
children = [...children, ...arr[i].childs];
}
}
if(!result && children.length) {
result = findObject(children, id);
}
return result;
}
console.log(findObject(objects, 4));
答案 1 :(得分:2)
您可以采用迭代和递归的方法。
function find(id, array) {
var result;
array.some(o => o.id === id && (result = o) || (result = find(id, o.children || [])));
return result;
}
var objects = [{ id: 1, name: 'foo' }, { id: 2, name: 'bar', children: [{ id: 3, name: 'baz', children: [{ id: 4, name: 'foobar' }] }] }];
console.log(find(1, objects));
console.log(find(2, objects));
console.log(find(3, objects));
console.log(find(4, objects));
.as-console-wrapper { max-height: 100% !important; top: 0; }
答案 2 :(得分:1)
您可以像这样递归地进行操作:
function deepFind(arr, search) {
for(var obj of arr) {
if(search(obj)) {
return obj;
}
if(obj.childs) {
var deepResult = deepFind(obj.childs, search);
if(deepResult) {
return deepResult;
}
}
}
return null;
}
然后像这样使用它:
var result = deepFind(objects, function(obj) {
return obj.id === myId;
});
示例:
function deepFind(arr, search) {
for(var obj of arr) {
if(search(obj)) {
return obj;
}
if(obj.childs) {
var deepResult = deepFind(obj.childs, search);
if(deepResult) {
return deepResult;
}
}
}
return null;
}
var objects = [{id: 1,name: 'foo'}, {id: 2,name: 'bar',childs: [{id: 3,name: 'baz',childs: [{id: 4,name: 'foobar'}]}]}];
console.log("ID 1:", deepFind(objects, obj => obj.id === 1));
console.log("ID 4:", deepFind(objects, obj => obj.id === 4));
console.log("ID 7:", deepFind(objects, obj => obj.id === 7));
答案 3 :(得分:0)
您可以使用递归功能并检查孩子
var objects = [{
id: 1,
name: 'foo'
}, {
id: 2,
name: 'bar',
childs: [{
id: 3,
name: 'baz',
childs: [{
id: 4,
name: 'foobar'
}]
}]
}];
let tempArray = [];
function doRecursiveSearch(obj, id) {
obj.forEach(function(item) {
console.log(item)
if (item.id === id) {
tempArray.push(item)
} else {
if (item.childs && Array.isArray(item.childs)) {
console.log(item)
doRecursiveSearch(item.childs, id)
}
}
})
}
doRecursiveSearch(objects, 4)
console.log(tempArray)