我试图了解ES2015中的生成器,并创建了一个递归因子函数.但它不行.我已经提到已经存在的问题,如
this这个话题,但这没有帮助.
function* fact (n) { if (n < 2) { yield 1; } else { yield* (n * fact(n-1)); } } let b = fact(5); console.log(b.next());
任何人都会发现我在这里遗失的明显问题吗?我在JSFiddle中使用了JavaScript-1.7 here
解决方法
Can anyone find any obvIoUs issues I am missing here?
事实返回一个迭代器,但是你试图用一个数字来重复它:n * fact(n-1).那不行!
因为事实返回一个迭代器,但是你也希望将迭代器的最后一个值乘以n(即它不是尾递归),所以你也不能简单地生成它.
您需要从内部调用中显式迭代结果,重新引用该值并记住最后一个值,以便可以使用多个值:
function* fact (n) { if (n < 2) { yield 1; } else { let last; for(last of fact(n-1)) { yield last; } yield n * last; } } Array.from(fact(5)); // [1,2,6,24,120]
如果您将函数更改为尾递归,则会稍微缩短(并且更好),但结果也会不同(因为我们以不同的顺序执行操作,至少在此实现中):
function* fact (n,acc=1) { yield acc if (n > 1) { yield* fact(n-1,acc * n); } } Array.from(fact(5)); // [1,5,20,60,120]
我个人只会写一个非递归版本:
function* fact (n) { let result = 1; let i = 0; while (i < n) { yield result = result * ++i; } } Array.from(fact(5)); // [1,120]