递归JavaScript函数正在丢失返回值

Ane*_*esh 4 javascript recursion json nested

我想在嵌套的JSON对象中搜索字符串.如果在对象中找到字符串,我需要返回该对象.

我正在使用递归函数来实现这一目标.问题是,函数递归到最后并且没有返回找到的对象.

请参阅jsfiddle中的完整代码

function search(obj, name) {
    console.log(obj["name"], ",", name, obj["name"] == name);

    if (obj["name"] == name) {
        return obj; //NOT RETURNING HERE
    } 
    if (obj.children || obj._children) {
        var ch = obj.children || obj._children;
        //console.log(ch);
        ch.forEach(function(val) {
            search(val, name)
        });
    }
    return -1;
}

search(myJson, "VM10-Proc4")
Run Code Online (Sandbox Code Playgroud)

我不确定出了什么问题.

Bar*_*mar 8

当找到匹配的子项时,您需要停止循环子项.

function search(obj, name) {

    console.log(obj.name, ",", name, obj.name == name);

    if (obj.name == name) {
        return obj;
    }
    if (obj.children || obj._children) {
        var ch = obj.children || obj._children;
        for (var i = 0; i < ch.length; i++) {
            var found = search(ch[i], name);
            if (found) {
                return found;
            }
        }
    }
    return false;
}
Run Code Online (Sandbox Code Playgroud)

FIDDLE演示


Mat*_*lin 5

正确的返回值在递归函数调用链中丢失了。找到正确的值后,从那时起进行的任何其他搜索都将返回不正确的值。

处理这个问题的几种方法:

1.取消搜索

当找到正确的值时,立即将其返回到递归堆栈中,不再搜索任何当前数组或嵌套数组。换句话说,取消其余的搜索。

@Barmer 的回答就是一个例子。他的代码的关键部分是使用for循环而不是each遍历数组的方法,因为中断for循环要容易得多。

2. 将值存储在安全的地方

找到正确的值后,将其存储在安全的地方,让其余的搜索继续进行,并在初始函数调用完成后访问该值。最简单的方法是将正确的值存储在全局变量中,但这不是一个好的做法,因为它违反了函数的封装。

@shyam 的回答提供了一个更简洁的解决方案:将全局变量的引用作为函数参数传递,在找到正确值时设置参数,然后在初始函数调用完成后访问全局变量。

在两者之间选择

通俗地说,这个函数的预期逻辑可以总结如下:当你找到你要找的东西时,停下来,并立即告诉我它是什么。继续搜索的唯一原因是需要找到多条数据。我假设这里不是这种情况。

在这两种方法中,#2 是一种快速修复的解决方法,它应该可以正常工作,但会进一步混淆任何试图理解函数预期逻辑的人。如果只查找已找到的单个数据,为什么还要继续搜索?

#1 是对函数的重构,使其行为更符合预期逻辑,这将使函数更易于理解。该函数在找到所需内容时停止搜索。