-
-
Save leobalter/092fc36adccfcc86e8e7b074817078e1 to your computer and use it in GitHub Desktop.
This file contains 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
// 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]; |
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)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.