-
-
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]; |
Hmm, interesting. What about add new reversed spread syntax?
const arr = [1,2,,3]
console.log([...arr]); // [ 1, 2, 3 ]
console.log([arr...]); // [ 3, 2, 1 ]
Second suggestion is use reversed
instead reverse
:
Array.prototype.reversed = Array.prototype[Symbol.reversed];
Map.prototype.reversed = Map.prototype[Symbol.reversed];
Set.prototype.reversed = Set.prototype[Symbol.reversed];
Please see https://github.com/leebyron/ecmascript-reverse-iterable for previous work in this area. Contemporary meeting notes probably have good discussions.
Wondering, why is reverseIterator
skipping over gaps when the regular iterator isn't ?
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.
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)
Will you like to add something like
for ... of reverse ...
syntax?Array.prototype.reverse() will mutate the original array. So maybe we should use other name?