admin管理员组文章数量:1225008
How can I get the nth value of a generator?
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
How can I get the nth value of a generator?
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
Share
Improve this question
asked May 23, 2015 at 7:57
MulanMulan
135k34 gold badges238 silver badges274 bronze badges
1
- 4 Have you tried a loop? – Bergi Commented May 23, 2015 at 8:00
5 Answers
Reset to default 6You can define an enumeration method like in python:
function *enumerate(it, start) {
start = start || 0;
for(let x of it)
yield [start++, x];
}
and then:
for(let [n, x] of enumerate(index()))
if(n == 6) {
console.log(x);
break;
}
http://www.es6fiddle.net/ia0rkxut/
Along the same lines, one can also reimplement pythonic range
and islice
:
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;
}
}
}
and then:
console.log(islice(index(), 6, 7).next().value);
http://www.es6fiddle.net/ia0s6amd/
A real-world implementation would require a bit more work, but you got the idea.
As T.J. Crowder pointed out, there is no way to get to the n
th element directly, as the values are generated on demand and only the immediate value can be retrieved with the next
function. So, we need to explicitly keep track of the number of items consumed.
The only solution is using a loop and I prefer iterating it with for..of
.
We can create a function like this
function elementAt(generator, n) {
"use strict";
let i = 0;
if (n < 0) {
throw new Error("Invalid index");
}
for (let value of generator) {
if (i++ == n) {
return value;
}
}
throw new Error("Generator has fewer than " + n + " elements");
}
and then invoke it like this
console.log(elementAt(index(), 10));
// 10
Another useful function might be, take
, which would allow you to take first n
elements from a generator, like this
function take(generator, n) {
"use strict";
let i = 1,
result = [];
if (n <= 0) {
throw new Error("Invalid index");
}
for (let value of generator) {
result.push(value);
if (i++ == n) {
return result;
}
}
throw new Error("Generator has fewer than " + n + " elements");
}
console.log(take(index(), 10))
// [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
A simple loop will do:
let n = 10,
iter = index();
while (--n > 0) iter.next();
console.log(iter.next().value); // 9
ECMAScript 2025 update: we now have iterator helper method drop
, and so we can now do:
const iter = gen(); // Generators return iterator helper objects
const value = iter.drop(n - 1).next().value
drop
returns an iterator that, when its first value is consumed, consumes the first n-1 values of the original iterator, ignoring them, and then yields the next one.
No array is created. If you want to have all first
本文标签: How to get the nth value of a JavaScript generatorStack Overflow
版权声明:本文标题:How to get the nth value of a JavaScript generator? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1739388014a2161029.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论