-
-
Save leobalter/092fc36adccfcc86e8e7b074817078e1 to your computer and use it in GitHub Desktop.
| // Motivation: we need a reverse iterator for list objects. | |
| // For Arrays, only reduceRight or decrementing loops | |
| // Currently impossible in Map/Set without a full loop or storing the list into an Array | |
| // Goal: a iterator that allows looping through the elements of a list from the last to the first element. Similar to .values() | |
| // Goal: it should not change the original array | |
| // Goal: it should allow interrupting the iteration. | |
| // Question: Should add equivalents to keys and entries? | |
| // Question: Names for the methods? | |
| Symbol.reverse = Symbol('reverseIterator'); | |
| function *reverse() { | |
| if (!this || typeof this !== 'object') { | |
| throw new TypeError('this is not an Object'); | |
| } | |
| const arr = this; | |
| let { length } = arr; | |
| while (length) { | |
| length = --length; | |
| if (!Object.prototype.hasOwnProperty.call(arr, length)) { | |
| continue; | |
| } | |
| yield arr[length]; | |
| // Dynamically jump to the last item in the array if it's shorter | |
| if (arr.length < length) { | |
| length = arr.length; // .next will jump to the latest existing value | |
| } | |
| } | |
| } | |
| Array.prototype[Symbol.reverse] = reverse; | |
| var array1 = [1, 2, 3, 4, 5]; | |
| console.log([...array1[Symbol.reverse]()]); // [5, 4, 3, 2, 1]; | |
| var obj = { | |
| length: 7, | |
| 6: 'a', | |
| get 5() { this.length = 1; return 'b'; }, | |
| 4: 'z', | |
| 1: 'z', | |
| 0: 'c' | |
| }; | |
| console.log([...Array.prototype[Symbol.reverse].call(obj)]); // [ 'a', 'b', 'c'] | |
| var array2 = [1,,2,,,3]; | |
| console.log([...array2[Symbol.reverse]()]); // [ 3, 2, 1 ] | |
| /* ------------------- */ | |
| // As methods: | |
| Array.prototype.reverseIterator = Array.prototype[Symbol.reverse]; // Needs bikesheding on the name!!! | |
| // Map and Set not drafted here | |
| Map.prototype.reverse = Map.prototype[Symbol.reverse]; | |
| Set.prototype.reverse = Set.prototype[Symbol.reverse]; |
This is not the “proposal source” and we plan to write down everything carefully. Please allow us a fair time considering the TC39 meeting is happening this week. I won’t use this motivation, neither rely on this gist only.
This is not the “proposal source”
It currently is, though -- this gist is the only thing that the agenda linked to, until the slides (which mostly contain the same info) were added. My point is exactly that: proposals should meet the entrance criteria before asking for stage advancement, and each of the criteria should be addressed in the repository/gist/README.
There is no requirement in the process document for it appearing specifically in any place including the readme; it does say "prose" which means we should indeed document things in writing somewhere, but it seemed a bit obvious since there's tons of usage in the wild of patterns like [...x].reverse() etc, so I don't think it occurred (to me at least) that it would be necessary to spell it out.
Now that it's stage 1, we will of course create a proper proposal repo and document it the conventional way.
(worth noting that this gist also ended up linking to https://github.com/leebyron/ecmascript-reverse-iterable as well which has much more motivation documented)
Champions, I’d like to request that you please check the entrance criteria and make sure there’s a README section for each item there. For example, “Motivation: we need a reverse iterator for list objects” is not a motivation.