我需要创建一个迭代无限序列的函数生成器,比如fibonacci序列。它应该在调用时返回序列中的下一个值。我得到了一个函数原型:
function genfib() {
return function fib() {
}
}
它应该像这样使用:
var fib = genfib();
fib(); // -> returns 0
fib(); // -> returns 1
fib(); // -> returns 1
fib(); // -> returns 2
每次拨打fib()
时,我都对执行的内容感到困惑。我试着做一些像
function genfib() {
var count = 1;
if (count === 1) {
count++;
yield 0;
}
else if (count === 2) {
count++;
yield 1;
}
var a = 0;
var b = 1;
return function fib() {
while(1) {
count = a + b;
a = b;
b = count;
yield count;
}
}
}
但它不起作用。我不知道如何设置它来为if/else
序列中的前两个数字运行fib
,然后为每个后续调用运行一次while
循环。
答案 0 :(得分:7)
如果您想使用ES6生成器和yield
,那么这就是方法:
function *fibonacci() {
var [prev, current] = [0, 1];
while (true) {
[prev, current] = [current, current+prev];
yield current;
}
}
迭代结果的一种方法是使用for-of
循环:
for (var v of fibonacci()) {
console.log(v);
if (v > 100) break;
}
请注意,FF和Traceur支持解构分配var [prev, current] =
,但目前不支持Chrome或节点。如有必要,请将其重写为:
function *fibonacci() {
var prev = 0, current = 1, oldprev;
while (true) {
oldprev = prev;
prev = current;
yield current += oldprev;
}
}
如果你想要给出函数原型的语义,那么:
function genfib() {
var iterator = fibonacci();
return function fib() {
return iterator.next().value;
};
}
答案 1 :(得分:2)
如果您问我,yield
在此功能中没有任何地方,只需巧妙地使用JavaScript closure。
你在开始时有正确的想法 - 你需要一个返回一个函数的函数。内部函数之外有几个变量 - 一个用于旧的,一个用于下一个。在函数内部,您所要做的就是计算新的next
值,然后将old
设置为next
之前的值。要切换它们的值,您需要一个占位符变量。
function genfib() {
var next = 1
var old = 0
return function fib() {
var newNext= next + old
old = next
next = newNext
return next
}
}
var fib = genfib()
var result = []
for ( var i = 0; i < 10; i++ )
result.push( fib() )
document.body.innerHTML = result.join()
&#13;
当然,这并不能解释第一个函数调用,这是一个特殊情况(1应该返回两次。)但是我会留给你弄清楚: - )< / p>
答案 2 :(得分:1)
function* fib(num) {
var a = num, b = a + 1, c = a;
while (true) {
yield a;
c = a;
a = b;
b = c + b;
}
}
var it = fib(0);
console.log(it.next().value); // 0
console.log(it.next().value); // 1
console.log(it.next().value); // 1
console.log(it.next().value); // 2
console.log(it.next().value); // 3
console.log(it.next().value); // 5
console.log(it.next().value); // 8
console.log(it.next().value); // 13
有关如何使用生成器的高级概述,checkout this post。
答案 3 :(得分:0)
function* fibonacci(){
var fn1 = 1;
var fn2 = 1;
while (true){
var current = fn2;
fn2 = fn1;
fn1 = fn1 + current;
var reset = yield current;
if (reset){
fn1 = 1;
fn2 = 1;
}
}
}
var sequence = fibonacci();
console.log(sequence.next().value); // 1
console.log(sequence.next().value); // 1
console.log(sequence.next().value); // 2
console.log(sequence.next().value); // 3
console.log(sequence.next().value); // 5
console.log(sequence.next().value); // 8
console.log(sequence.next().value); // 13
console.log(sequence.next(true).value); // 1
console.log(sequence.next().value); // 1
console.log(sequence.next().value); // 2
console.log(sequence.next().value); // 3