Is it possible to access the previous value of an iterator, for example:
function* gen () {
yield* [0,1,2,3]
}
var it = gen();
it.next().value // 0
it.next().value // 1
it.last().value // would be awesome if this was 0
This is strictly a curiosity question. I've been playing with generators lately and was wondering if anyone uses generators/iterators in this manner?
If so, I would love to see your solution. (Doesn't need to follow the above syntax) -Thanks
Is it possible to access the previous value of an iterator, for example:
function* gen () {
yield* [0,1,2,3]
}
var it = gen();
it.next().value // 0
it.next().value // 1
it.last().value // would be awesome if this was 0
This is strictly a curiosity question. I've been playing with generators lately and was wondering if anyone uses generators/iterators in this manner?
If so, I would love to see your solution. (Doesn't need to follow the above syntax) -Thanks
Share Improve this question edited Jun 8, 2017 at 16:04 Andrew Li 58k14 gold badges134 silver badges148 bronze badges asked Jun 8, 2017 at 15:53 Joseph BarnesJoseph Barnes 6405 silver badges10 bronze badges 6-
2
By
last
do you mean the previous value? – Michał Perłakowski Commented Jun 8, 2017 at 15:59 - I meant the previous yield...Do you think I should reformat the code to make that more clear? – Joseph Barnes Commented Jun 8, 2017 at 16:03
- You cannot. The iterator protocol doesn't provide such an API. – Felix Kling Commented Jun 8, 2017 at 16:07
- @FelixKling But you can make a wrapper for generators; see my answer. – Michał Perłakowski Commented Jun 8, 2017 at 16:08
- @MichałPerłakowski: Sure, one can always implement their own solution :) – Felix Kling Commented Jun 8, 2017 at 16:09
3 Answers
Reset to default 5JS iterators only know one direction: forwards. Meaning, if you would want to use your custom iterator with a for-loop or the like, it would ignore your custom properties. You could however create your own custom iterator for your own use only:
const obj = {
values: [0,1,2,3],
[Symbol.iterator]() {
const values = this.values;
const min = 0;
const max = values.length - 1;
let index = -1;
return {
next() {
index = Math.min(index + 1, max);
return { value: values[index], done: index >= max };
},
prev() {
index = Math.max(index - 1, min);
return { value: values[index], done: index <= min };
}
}
}
}
var it = obj[Symbol.iterator]();
console.log(it.next().value); // 0
console.log(it.next().value); // 1
console.log(it.prev().value); // would be awesome if this was 0
console.log(it.prev().value); // would be awesome if this was 0
console.log(it.prev().value); // would be awesome if this was 0
console.log(it.next().value); // would be awesome if this was 1
You can wrap the generator in a function that saves previous yields:
const wrapGenerator = gen => (...args) => {
const it = gen(...args);
let previous, current;
return {
next: () => {
const r = it.next();
previous = current;
current = r.value;
return r;
},
previous: () => ({ value: previous })
};
};
const gen = wrapGenerator(function * () {
yield * [0, 1, 2, 3];
});
const it = gen();
console.log(it.next().value);
console.log(it.next().value);
console.log(it.previous().value);
I changed the function name to previous
to avoid confusion (last
could mean "the last item").
No, this is not generally possible. Iterators can only be advanced, not reversed or anything else.
Of course you can write your own iterator wrapper that caches the last value and makes it accessible in whatever way you like.
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745229851a4617627.html
评论列表(0条)