如何获取JavaScript生成器的第n个值?

Tha*_*you 4 javascript generator ecmascript-6

如何获得生成器的第n个值?

function *index() {
  let x = 0;
  while(true)
    yield x++;
}

// the 1st value
let a = index();
console.log(a.next().value); // 0

// the 3rd value
let b = index();
b.next();
b.next();
console.log(b.next().value); // 2

// the nth value?
let c = index();
let n = 10;
console.log(...); // 9
Run Code Online (Sandbox Code Playgroud)

geo*_*org 5

您可以在python中定义枚举方法:

function *enumerate(it, start) {
   start = start || 0;
   for(let x of it)
     yield [start++, x];
}
Run Code Online (Sandbox Code Playgroud)

然后:

for(let [n, x] of enumerate(index()))
  if(n == 6) {
    console.log(x);
    break;
  }
Run Code Online (Sandbox Code Playgroud)

http://www.es6fiddle.net/ia0rkxut/

沿着同样的路线,人们也可以重新实现pythonic rangeislice:

function *range(start, stop, step) {
  while(start < stop) {
    yield start;
    start += step;
  }
}

function *islice(it, start, stop, step) {
  let r = range(start || 0, stop || Number.MAX_SAFE_INTEGER, step || 1);
  let i = r.next().value;
  for(var [n, x] of enumerate(it)) {
    if(n === i) {
      yield x;
      i = r.next().value;
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

然后:

console.log(islice(index(), 6, 7).next().value);
Run Code Online (Sandbox Code Playgroud)

http://www.es6fiddle.net/ia0s6amd/

实际的实现需要更多的工作,但你明白了.


Tha*_*you 0

我想避免不必要地创建数组或其他中间值。这就是我的实现的结果nth-

function nth (iter, n)
{ for (const v of iter)
    if (--n < 0)
      return v
}
Run Code Online (Sandbox Code Playgroud)

按照原始问题中的示例 -

// the 1st value
console.log(nth(index(), 0))

// the 3rd value
console.log(nth(index(), 2))

// the 10th value
console.log(nth(index(), 9))
Run Code Online (Sandbox Code Playgroud)
0
2
9
Run Code Online (Sandbox Code Playgroud)

对于有限生成器,如果索引越界,结果将是undefined-

0
2
9
Run Code Online (Sandbox Code Playgroud)
function* foo ()
{ yield 1
  yield 2
  yield 3
}

console.log(nth(foo(), 99))
Run Code Online (Sandbox Code Playgroud)

展开下面的代码片段以验证浏览器中的结果 -