Javascript 什么是;返回a";在这个递归组合函数中是什么?
我在Chrome调试器中反复检查了这个函数,但仍然不明白Javascript 什么是;返回a";在这个递归组合函数中是什么?,javascript,recursion,permutation,Javascript,Recursion,Permutation,我在Chrome调试器中反复检查了这个函数,但仍然不明白返回a的作用。谢谢你帮助我 以下是一些澄清: 我理解第一轮。使用以下参数调用匿名函数: active=“”,rest=“abc”,a=[] 然后,当它填充a数组时,它调用自己,直到rest为空: active=“abc”,rest=“”,a=[“abc”] 此时,我们将返回一个,调试器将跳转到else语句中的第二个fn调用,而不是第一个if语句。参数已经如下所示: active=“ab”,rest=“c”,a=[“abc”] 这部分我一点也
返回a
的作用。谢谢你帮助我
以下是一些澄清:
我理解第一轮。使用以下参数调用匿名函数:
active=“”,rest=“abc”,a=[]
然后,当它填充a
数组时,它调用自己,直到rest
为空:
active=“abc”,rest=“”,a=[“abc”]
此时,我们将返回一个,调试器将跳转到else语句中的第二个fn调用,而不是第一个if语句。参数已经如下所示:
active=“ab”,rest=“c”,a=[“abc”]
这部分我一点也不懂。我知道递归只有在active
和rest
为空时才会结束,但在返回a
之后,if语句甚至没有在调试器中得到检查,它只会突出显示提到的第二个函数调用,此时“c”已经分配给rest
。我猜这个函数不产生副本的原因也在这里,但如果不是,那可能是另一个问题。无论如何,再次感谢你的帮助
combinations("abc");
function combinations(str) {
var fn = function(active, rest, a) {
if (!active && !rest)
return;
if (!rest) {
a.push(active);
} else {
fn(active + rest[0], rest.slice(1), a);
fn(active, rest.slice(1), a);
}
return a;
}
return fn("", str, []);
}
在这种情况下,递归构造编写得很奇怪,“returna”只是将最初提供的相同对象的变异数组偷偷带回到helper函数,以便在内部递归函数调用中使用直接返回。(在大多数上下文中,递归函数通常使用返回值。) 下面是一个更清晰的使用helper函数的重写。我还删除了所有显式返回语句,因为它们没有在这里增加值
function combinations(str) {
var fn = function(active, rest, a) {
if (!active && !rest) {
// base case #1 - implicit return, no recursive call
} else if (!rest) {
// base case #2 - implicit return, no recursive call
a.push(active);
} else {
// recursive case, where function is called again
// (the object "a" is modified in recursion;
// result of recursion not directly used)
fn(active + rest[0], rest.slice(1), a);
fn(active, rest.slice(1), a);
}
}
var o = []; // only one output object created..
fn("", str, o); // ..mutated..
return o; // ..and returned to caller.
}
然后应该很容易观察到,不需要将“a”传递给递归函数(即,它可以访问封闭范围中的“o”),因为在创建初始结果数组之后,没有为“a”分配新对象
重新写入将(更正确地)为空输入字符串返回一个空数组。在这种情况下,递归构造写得很奇怪,“返回a”只是为了偷偷输出变异数组,即最初提供的相同对象,返回helper函数,以便在内部递归函数调用中使用直接返回。(在大多数上下文中,递归函数通常使用返回值。) 下面是一个更清晰的使用helper函数的重写。我还删除了所有显式返回语句,因为它们没有在这里增加值
function combinations(str) {
var fn = function(active, rest, a) {
if (!active && !rest) {
// base case #1 - implicit return, no recursive call
} else if (!rest) {
// base case #2 - implicit return, no recursive call
a.push(active);
} else {
// recursive case, where function is called again
// (the object "a" is modified in recursion;
// result of recursion not directly used)
fn(active + rest[0], rest.slice(1), a);
fn(active, rest.slice(1), a);
}
}
var o = []; // only one output object created..
fn("", str, o); // ..mutated..
return o; // ..and returned to caller.
}
然后应该很容易观察到,不需要将“a”传递给递归函数(即,它可以访问封闭范围中的“o”),因为在创建初始结果数组之后,没有为“a”分配新对象
重写将(更正确地)为空输入字符串返回一个空数组,这有一个微妙的区别。虽然我知道这个问题主要是关于特定递归实现的工作原理(对此已经有一个很好的答案!),但我认为值得指出的是,它是一个奇怪的实现,像这样的东西可能更干净:
const组合=(str,active=“”)=>
str.length==0
? 活动。长度==0
? []
:[现行]
: [
…组合(str.slice(1),active+str[0]),
…组合(str.slice(1),活动)
]
log(combinations('abc'))
虽然我知道这个问题主要是关于特定递归实现的工作原理(对此已经有了一个很好的答案!),但我认为值得指出的是,它是一个奇怪的实现,类似这样的实现可能更干净:
const组合=(str,active=“”)=>
str.length==0
? 活动。长度==0
? []
:[现行]
: [
…组合(str.slice(1),active+str[0]),
…组合(str.slice(1),活动)
]
log(combinations('abc'))
它从递归返回,这意味着在返回之后,它将到达调用它的行。然后是第二行,进行第二次调用。函数的布局很奇怪。。也就是说,返回应该始终为“return;”(或者更好,两个返回都被消除!),并且helper函数应该返回经过修改的对象本身。那么,结尾的“return a;”显然是多余的。如上所述,“return a;”仅用于输出变异对象(假设终端大小写不是立即为真的),它本身与递归无关。@user2864740谢谢你的回答,我现在明白了!但最主要的是(因为我不小心删除了我以前的注释),第一个调用的参数被传递到第二个调用。@Premierplan如果它们被显式指定,则是:)这是由fn(…,…,a)
eg.完成的,它与返回无关。它是从递归返回的,这意味着在返回之后
将到达调用它的行。然后是第二行,进行第二次调用。函数的布局很奇怪。。也就是说,返回应该始终为“return;”(或者更好,两个返回都被消除!),并且helper函数应该返回经过修改的对象本身。那么,结尾的“return a;”显然是多余的。如上所述,“return a;”仅用于输出变异对象(假设终端大小写不是立即为真的),它本身与递归无关。@user2864740谢谢你的回答,我现在明白了!但最主要的是(因为我不小心删除了之前的注释),第一个调用的参数被传递到第二个调用。@Premierplan如果它们被显式指定,则为yes:)这是通过