Skip to content

Instantly share code, notes, and snippets.

@leobalter leobalter/reverseIterator.js Secret
Last active Jul 25, 2019

Embed
What would you like to do?
// 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];
@hax

This comment has been minimized.

Copy link

commented Jul 6, 2019

  1. Will you like to add something like for ... of reverse ... syntax?

  2. Array.prototype.reverse() will mutate the original array. So maybe we should use other name?

@MaxGraey

This comment has been minimized.

Copy link

commented Jul 6, 2019

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];
@domenic

This comment has been minimized.

Copy link

commented Jul 6, 2019

Please see https://github.com/leebyron/ecmascript-reverse-iterable for previous work in this area. Contemporary meeting notes probably have good discussions.

@mhofman

This comment has been minimized.

Copy link

commented Jul 24, 2019

Wondering, why is reverseIterator skipping over gaps when the regular iterator isn't ?

@mathiasbynens

This comment has been minimized.

Copy link

commented Jul 24, 2019

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.

@leobalter

This comment has been minimized.

Copy link
Owner Author

commented Jul 24, 2019

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.

@mathiasbynens

This comment has been minimized.

Copy link

commented Jul 25, 2019

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.

@ljharb

This comment has been minimized.

Copy link

commented Jul 25, 2019

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
You can’t perform that action at this time.