使用while循环而不是循环进行迭代
ECMAScript 6为迭代引入了生成器,迭代器和语法糖。 带有标志的Node.JS v0.11.4
--harmony --use_strict --harmony_generators
了解以下发电机
function* fibonacci() { let previous = 0; let current = 1; while(true) { let temp = previous; previous = current; yield current = temp + current; } }
然后我可以打印小于1000的斐波那契数。
for(let value of fibonacci()) { if(value > 1000) { break; } console.log(value); }
对于这个例子, while
循环代替for
循环会更自然,类似于
while(value of fibonacci() < 1000) { console.log(value); }
迭代器的迭代可以使用while
循环而不是for
循环来完成吗?
这样会满足你吗?
var sequence = fibonacci(); var value; while ((value = sequence.next()) < 1000) { console.log(value); }
再加上,甚至更好的解决scheme可能是这样的:
function* fibonacci(limit){ let previous = 0; let current = 1; while(previous + current < limit) { let temp = previous; previous = current; yield current = temp + current; } } for(let value of fibonacci(1000)) { console.log(value); }
有两种可能的方法我会继续这个,给予其他语言,支持这种行为:
1)一个使用和谐代理,这将让你做元表(有点像在卢阿 ),并允许惰性iterables。 这将提供以下符号:
var arr = ...; // create the resource for(var i=0;arr[i]<1000;i++){ arr[i]; // consume fibonacci numbers }
2)第二个使用take
函数让你消耗一个迭代.forEach
像在C#或python中 。 这将允许以下表示法:
takeWhile(fibGenerator,(item) => item<1000).forEach(... // consume with predicate
第一种方法 – 使用和谐代理
注意…通过对象循环。 它并不能保证顺序。 然而,你可以做类似下面的事情来得到一个惰性迭代的概念。
您必须使用--harmony_generators
和--harmony_proxies
标志运行节点:
var arr = ...; // create an array and proxy it, use a generator internally arr[50]; // will calculate the 50th fibonacci element and return it. arr[100];// will calculate the 100th fibonacci element and return it. for(var i=0;arr[i]<1000;i++){ arr[i];//the i-th fibonacci number }
它只会计算尚未提取的数字,这将允许您使用简单的for
循环。
这里是如何*:
var cache = []; var handler = { get: (function(){ function fibIterator(){ var t=0,a=0,b=0; return function(){ t=a; a+=b; b=t; return a; } } var iterator = fibIterator(); return function (target, fibNumber) { if (name in cache) { return cache[name]; } while(iterator < fibNumber){ // update indexes. } })() } }; var arr = Proxy.create(handler);
(只是不要指望它会很快)
*(使用旧代理符号,因为新节点不支持节点,一旦得到支持就会更新)
注意,在JavaScript中,因为函数可以通过闭包拥有内部状态,所以甚至不需要生成器
第二种方法,使用迭代器Take
function。
这就是你通常在C#这样的语言中使用的例子。
function takeWhile(generating, predicate){ var res = [],last; do{ res.push(last=generating()) }while(predicate(last)); return res; }
然后做一些像
var res = takeWhile(fibIterator,function(item){ return item<1000; }); res.forEach(function(){ ...
或者通过计数:
function take(generating,numToTake){ var res = [],num; do{ res.push(last=generating()) }while(num++ < numToTake); return res; } var res = take(fibIterator,1000);//first 1000 numbers
function *bar(){ yield 1; yield 2; yield 3; return 4; } var value, g = bar(); while((value = g.next()).value){ console.log(value); } //Object {value: 1, done: false} //Object {value: 2, done: false} //Object {value: 3, done: false} //Object {value: 4, done: true}
是的,可以通过使用常规生成器方法来完成此操作。
var fib = fibonacci(), value; while( (value = fib.next()) < 1000 ) { console.log(value); }
尽pipe我似乎更喜欢处理下一个调用和处理StopIteration
(如果序列是有限的)的处理语句。