假设我有一个像这样的嵌套对象:
{
label: 'parent',
eyeColor: 'brown',
kids: [
{
label: 'kid_0',
eyeColor: 'brown',
kids: [
{
label: 'kid_0_0',
eyeColor: 'green',
kids: []
},
{
label: 'kid_0_1',
eyeColor: 'brown',
kids: [
{
label: 'kid_0_1_0',
eyeColor: 'brown',
kids: []
}
]
}
],
},
{
label: 'kid_1',
eyeColor: 'brown',
kids: [
{
label: 'kid_1_0',
eyeColor: 'brown',
kids: []
}
],
},
{
label: 'kid_2',
eyeColor: 'green',
kids: []
}
]
};
如果我想存储所有唯一路径,我将如何递归地执行此操作?我尝试了很多尝试,但我似乎无法获得独特的路径(我的路径建立在以前的路径之上)。
所以我的预期输出是:
[
['parent', 'kid_0', 'kid_0_0],
['parent', 'kid_0', 'kid_0_1, kid_0_1_0],
['parent', 'kid_1', 'kid_1_0],
['parent', 'kid_2]
]
但是如果我想找到一个除了eyeColor
之外的brown
的孩子或节点时我想停止路径,那么路径就会停在那里。然后需要改变以获得以下内容:
[
['parent', 'kid_0', 'kid_0_1, kid_0_1_0],
['parent', 'kid_1', 'kid_1_0],
]
这是我当前的代码,现在错误输出最大调用堆栈的b / c。
var printPaths = function(node, color) {
var paths = [];
var trackPath = function(obj, feature, path) {
if (obj.eyeColor === 'brown') {
path.push(node.label);
} else if (obj.eyeColor !== 'brown') {
paths.push(path);
} else if (obj.kids.length === 0) {
paths.push(path);
}
for (var i = 0; i < obj.kids.length; i++) {
trackPath(obj.kids[i], feature, path)
path.pop();
}
};
trackPath(node, color, []);
return paths;
}
答案 0 :(得分:1)
你的方法很好,唯一的问题是assignment or argument passing doesn't copy arrays。在递归中引入slice()
调用:
function printPaths(node, color) {
var paths = [];
function trackPath(obj, feature, path) {
if (obj.eyeColor !== feature) { // found target
paths.push(path);
return;
} // else continue
path.push(obj.label);
for (var i = 0; i < obj.kids.length; i++) {
trackPath(obj.kids[i], feature, path.slice());
// ^^^^^^^^
}
}
trackPath(node, color, []);
return paths;
}
答案 1 :(得分:0)
这是我的方法,我必须重写你的逻辑以及使用切片
进行数组复制var printPaths = function(node, color) {
var paths = [];
var trackPath = function(obj, feature, path) {
//debugger;
path.push(obj.label);
if (obj.eyeColor === 'brown') {
if (obj.kids.length == 0) {
paths.push(path.slice());
}
else {
for (var i = 0; i < obj.kids.length; i++) {
trackPath(obj.kids[i], feature, path);
}
}
}
path.pop();
};
trackPath(node, color, []);
return paths;
}
答案 2 :(得分:0)
这是我最终开始工作的解决方案。我得到了@Bergi的帮助,但他的解决方案并没有完全符合我的需要。这个解决方案超越了我写的所有测试。
var printPaths = function(node, color) {
var paths = [];
var trackPath = function(obj, feature, path) {
// if the current node has the desired property, push that
// to the current path, then continue checking checking
// if there are any children (two if statements down)
if (obj.eyeColor === feature) {
path.push(obj.label);
}
// if we encounter a path that isn't our desired property,
// don't push the current node on to the current path, but instead
// just push the failed path, and return, so that it doesn't
// continue to check
if (obj.eyeColor !== feature) {
paths.push(path);
return;
}
// if we're at a leaf node, i.e we had a full successful path
// (everyone had brown eyes)
if (obj.kids.length === 0) {
paths.push(path);
}
for (var i = 0; i < obj.kids.length; i++) {
trackPath(obj.kids[i], feature, path.slice())
}
};
trackPath(node, color, []);
return paths;
}