Last active
August 29, 2015 13:56
-
-
Save getify/9105362 to your computer and use it in GitHub Desktop.
Exploring why I wish ES6's `for-of` had a syntax for sending in values to each iteration's `next(..)` call
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This example shows a simple data structure object that holds | |
// a sequence of numbers from 0 to 99. It defines its own iterator | |
// which lets you dump all those values out using a `for-of` loop. | |
// | |
// Note: the iterator accepts a value to `next(..)` which represents | |
// a step value, if you wanted to get only every nth value from | |
// the sequence. | |
// | |
// Unfortunately, ES6's for-of doesn't have a syntax for passing in | |
// a value to that default per-iteration `next(..)` call that occurs. :( | |
var myNumbers = (function(){ | |
var d = []; | |
for (var i=0; i<100; i++) { | |
d.push(i); | |
} | |
var publicAPI = {}; // no need for an API, can only be iterated on! | |
Object.defineProperty(publicAPI,Symbol.iterator,{ | |
configurable: false, | |
enumerable: false, | |
writable: false, | |
value: function() { | |
var idx = -1; | |
var data = d.slice(); // make a temp copy of internal data so we can iterate on it! | |
return { | |
// step would let you get only every nth number | |
next: function(step) { | |
idx += (+step || 1); | |
var v = data[idx]; | |
return { done: (idx >= data.length), value: v }; | |
} | |
}; | |
} | |
}); | |
return publicAPI; | |
})(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Here's just the standard ES6 `for-of` iteration, which | |
// could only just get out all numbers, not every nth number | |
// in the sequence. :( | |
for (var v of myNumbers) { | |
console.log(v); | |
} | |
// prints out all 100 numbers 0..99 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Here's an exploration of a rough possible syntax extension to `for-of` | |
// that would let you pass in a value to each iteration's `next(..)`, | |
// which would let you get out every nth number of the number sequence. | |
// | |
// The `:3` syntax would specify a value that should be passed in to every | |
// `next(..)` call of the iterator. | |
for (var v of myNumbers:3) { | |
console.log(v); | |
} | |
// prints out every 3rd number: 2, 5, 8, ... |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Here's showing the syntax could take a variable for the `next(..)` | |
// argument, instead of a fixed number, so we can do a stepped-iteration. | |
var step = 1; | |
for (var v of myNumbers:step) { | |
console.log(v); | |
step++; // increase the next step-value each time | |
} | |
// prints out 0, 2, 5, 9, 14, 20, ... | |
// | |
// step of `1` yields `0` | |
// step of `2` yields `2` | |
// step of `3` yields `5` | |
// step of `4` yields `9` | |
// step of `5` yields `14` | |
// step of `6` yields `20` | |
// ... |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Here's I show how, without the `for-of` syntax I propose, | |
// you have to do the stepped-iteration manually. :( | |
for (var step = 1, it = myNumbers[Symbol.iterator](), ret; | |
// call `next(..)` on the number sequence's iterator | |
!(ret && ret.done) && (ret = it.next(step)); | |
) { | |
console.log(ret.value); | |
step++; | |
} | |
// prints out 0, 2, 5, 9, 14, 20, ... | |
// | |
// step of `1` yields `0` | |
// step of `2` yields `2` | |
// step of `3` yields `5` | |
// step of `4` yields `9` | |
// step of `5` yields `14` | |
// step of `6` yields `20` | |
// ... |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@allenwb hmm, very interesting. thanks so much for the thoughtful post. i'll see if i can make something like that work in my real use-case.
still wish we had a direct syntax for it, b/c as I showed in the 5th snippet, it IS possible to do it, just dislike having to try harder for seemingly simple features.
obviously, your's is better since it actually uses the
for-of
instead of just afor;;
like mine. the third example feels weird to have to use a function-closure to transport value(s) into the iteration machinery at each step, but it might just be the best I can do. :)