如何查看 Javascript 迭代器中的下一个值
How to peek at the next value in a Javascript Iterator
假设我有一个迭代器:
function* someIterator () {
yield 1;
yield 2;
yield 3;
}
let iter = someIterator();
...我看下一个要迭代的元素:
let next = iter.next(); // {value: 1, done: false}
...然后我在循环中使用迭代器:
for(let i of iterator)
console.log(i);
// 2
// 3
循环将不包括查看的元素。我希望在不将其从迭代系列中取出的情况下看到下一个元素。
换句话说,我想实现:
let next = peek(iter); // {value: 1, done: false}, or alternatively just 1
for(let i of iterator)
console.log(i);
// 1
// 2
// 3
...如果不修改可迭代函数的代码,我不想这样做。
我尝试过的在我的回答中。它有效(这就是我将其作为答案的原因),但我担心它构建的对象比它必须的更复杂。我担心它不适用于 'done' 对象不同于 { value = undefined, done = true }
的情况。因此,非常欢迎任何改进的答案。
我构建了一个调用 next
的 peeker
函数,而不是 peek
函数,从迭代器中删除元素,然后通过创建可迭代函数将其添加回去首先产生捕获的元素,然后产生迭代中的剩余项目。
function peeker(iterator) {
let peeked = iterator.next();
let rebuiltIterator = function*() {
if(peeked.done)
return;
yield peeked.value;
yield* iterator;
}
return { peeked, rebuiltIterator };
}
function* someIterator () { yield 1; yield 2; yield 3; }
let iter = someIterator();
let peeked = peeker(iter);
console.log(peeked.peeked);
for(let i of peeked.rebuiltIterator())
console.log(i);
只是有点不同的想法是使用使迭代器更容易的包装器。
function peekable(iterator) {
let state = iterator.next();
const _i = (function* (initial) {
while (!state.done) {
const current = state.value;
state = iterator.next();
const arg = yield current;
}
return state.value;
})()
_i.peek = () => state;
return _i;
}
function* someIterator () { yield 1; yield 2; yield 3; }
let iter = peekable(someIterator());
let v = iter.peek();
let peeked = iter.peek();
console.log(peeked.value);
for (let i of iter) {
console.log(i);
}
假设我有一个迭代器:
function* someIterator () {
yield 1;
yield 2;
yield 3;
}
let iter = someIterator();
...我看下一个要迭代的元素:
let next = iter.next(); // {value: 1, done: false}
...然后我在循环中使用迭代器:
for(let i of iterator)
console.log(i);
// 2
// 3
循环将不包括查看的元素。我希望在不将其从迭代系列中取出的情况下看到下一个元素。
换句话说,我想实现:
let next = peek(iter); // {value: 1, done: false}, or alternatively just 1
for(let i of iterator)
console.log(i);
// 1
// 2
// 3
...如果不修改可迭代函数的代码,我不想这样做。
我尝试过的在我的回答中。它有效(这就是我将其作为答案的原因),但我担心它构建的对象比它必须的更复杂。我担心它不适用于 'done' 对象不同于 { value = undefined, done = true }
的情况。因此,非常欢迎任何改进的答案。
我构建了一个调用 next
的 peeker
函数,而不是 peek
函数,从迭代器中删除元素,然后通过创建可迭代函数将其添加回去首先产生捕获的元素,然后产生迭代中的剩余项目。
function peeker(iterator) {
let peeked = iterator.next();
let rebuiltIterator = function*() {
if(peeked.done)
return;
yield peeked.value;
yield* iterator;
}
return { peeked, rebuiltIterator };
}
function* someIterator () { yield 1; yield 2; yield 3; }
let iter = someIterator();
let peeked = peeker(iter);
console.log(peeked.peeked);
for(let i of peeked.rebuiltIterator())
console.log(i);
只是有点不同的想法是使用使迭代器更容易的包装器。
function peekable(iterator) {
let state = iterator.next();
const _i = (function* (initial) {
while (!state.done) {
const current = state.value;
state = iterator.next();
const arg = yield current;
}
return state.value;
})()
_i.peek = () => state;
return _i;
}
function* someIterator () { yield 1; yield 2; yield 3; }
let iter = peekable(someIterator());
let v = iter.peek();
let peeked = iter.peek();
console.log(peeked.value);
for (let i of iter) {
console.log(i);
}