Is it possible to define an array iterator that adjusts to your for-of syntax?
It is not possible to detect this.
for (let [i, elem] of arr){
is no different that than
for (let pair of arr){
let [i, elem] = pair;
You are destructuring the result of an iterator, and the initialization of the iterator is independent from the initialization of the destructuring pattern.
On May 22, 2016, at 1:55 PM, Šime Vidas <sime.vidas at gmail.com> wrote:
Say I have an array over which I need to iterate multiple times, but I need the index value only some of the time. Is it possible to create a custom iterator which auto-detects when I need the index and feeds me entries() instead of values() in those cases? For example:
array[Symbol.iterator] = /* some magic here */
for (let elem of array) { /* values() iterator is used automatically / } for (let [i, elem] of array) { / entries() iterator is used automatically */ }
The ES internal protocol design assumes that you would to this as follows:
for (let elem of array.entries()) { /* values() iterator is explicitly used / } for (let [i, elem] of array.elements()) { / entries() iterator is explicitly used */ }
No magic is necessary.
No, it's not possible.
Oddly enough, when this functionality was first prototyped in SpiderMonkey many years ago, the iterator protocol did pass a boolean to the iterator method (this was before symbols) based on the syntax you were using to unpack the results. This feature was not super useful in practice, and I always thought it was too subtle -- the difference in syntax was really not explicit enough to make it clear to the programmer what was going on. I'm glad it wasn't standardized.
There could be a protocol for defining the shape of the iterator's returns, but it would need to use functions instead of the loop syntax. I've previously suggested something like:
iterator[Symbol.shape] = Symbol.shape.entries
Then a generic iteration function supporting this interface would know that the iterator returns entries (key/value pairs) and pass them as separate parameters to the callback. Something like:
map(iterator, (key, value) => ...)
The benefit of this is kind of trivial, though, since all you save yourself
from doing is writing ([key, value])
for the callback function parameters.
R. untu.ms
Say I have an array over which I need to iterate multiple times, but I need the index value only some of the time. Is it possible to create a custom iterator which auto-detects when I need the index and feeds me entries() instead of values() in those cases? For example:
array[Symbol.iterator] = /* some magic here */
for (let elem of array) { /* values() iterator is used automatically / } for (let [i, elem] of array) { / entries() iterator is used automatically */ }