我想迭代一个结构,将选定的节点推送到一个数组并返回所有节点。
var structure = {
folder: getFolder(1, 'name1'),
children: [
{
folder: getFolder(2, 'name2'),
children: [
{
folder: getFolder(4, 'name2'),
children: []
}
]
},
{
folder: getFolder(3, 'name3'),
children: []
}
]
};
例如,如果文件夹节点与 getFolder(x, 'name2') 匹配,我将得到一个包含两个元素的数组:
folder: getFolder(2, 'name2'),
children: [
{
folder: getFolder(4, 'name2'),
children: []
}
]
和
folder: getFolder(4, 'name2'),
children: []
因为两者都符合给定的条件。我想出的功能是:
var searchAll = function (data, searchFor, results) {
results = results || [];
if (data[searchFor.type] != undefined &&
data[searchFor.type][searchFor.index].indexOf(searchFor.value) !== -1) {
return data;
}
if (data.children != null) {
var result = null;
for (var i = 0; result == null && i < data.children.length; i++) {
results.push(searchAll(data.children[i], searchFor, results));
}
}
return results;
};
searchAll(structure, {
type: 'folder',
index: 'name',
value: 'name2'
});
但它返回未定义。我该怎么做?
最佳答案
用递归构建数组的关键是 concat()方法,它将正确返回数组的副本,一直到递归堆栈。
在下面的示例中,与您的条件相匹配的对象将通过 Push() 添加,而子对象将被递归搜索,并且它们的结果将连接到结果数组中。为简单起见,我使用了 getFolder()
函数在数据中返回的结果:
var structure = {
folder: {id:1, name:'name1'}, //getFolder(1, 'name1'),
children: [{
folder: {id:2, name:'name2'}, //getFolder(2, 'name2'),
children: [{
folder: {id:4, name:'name2'}, //getFolder(4, 'name2'),
children: []
}]
}, {
folder: {id:3, name:'name3'}, //getFolder(3, 'name3'),
children: []
}]
};
function searchAll(object, criteria) {
var i, j, result = [];
for (i in object) {
if (i === criteria.type && object[i][criteria.index] === criteria.value) {
result.push(object);
} else if (i === 'children' && object[i].length > 0) {
for (j = 0; j < object[i].length; j++) {
result = result.concat(searchAll(object[i][j], criteria));
}
}
}
return result;
}
console.log(searchAll(structure, {type: 'folder', index: 'name', value: 'name2'}));
编辑:链接到 JSFiddle 因为看起来 SO 代码片段停止了递归,结果应该是正确的(2 个对象包含您想要的数据) https://jsfiddle.net/fswmxk7h/
关于javascript - 插入数组并从递归函数返回它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39467754/