考虑到支持这种行为的其他语言,我有两种可能的方式来解决这个问题:
1)一个使用 Harmony 代理,它可以让你做元表(有点像lua)并允许惰性迭代。这将提供以下符号:
var arr = ...; // create the resource
for(var i=0;arr[i]<1000;i++){
arr[i]; // consume fibonacci numbers
}
2) 第二个使用一个函数,让您使用C#或python中take
的可迭代对象。这将允许以下符号:.forEach
takeWhile(fibGenerator,(item) => item<1000).forEach(... // consume with predicate
第一种方法 - 使用和谐代理
注意...for of
循环对象。它根本不保证顺序。但是,您可以执行以下操作来获得惰性迭代的概念。
您必须使用--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
函数。
对于此用例,这是您通常使用 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