While John's solution doesn't run into conflicts with downward compatibility, 
it still wouldn't solve the problem of getting the n-th last element of an 
array. To solve this, it'd probably be a good idea to extend the prototype and 
specify a parameter, defaulting to 1.

`Array.prototype.last` doesn't show up a terrible lot on search engines, 
either, so we might actually be lucky here. Other than that, I also found two 
more threads[1][2] on the EcmaScript discussion archives that propose it.

They might be worth a read.

[1] https://esdiscuss.org/topic/array-prototype-last
[2] https://esdiscuss.org/topic/proposal-array-prototype-last

On Samstag, 23. Januar 2016 15:44:19 CET John Gardner wrote:
> Using a well-known symbol to access an array's last element is probably
> wiser than a typical method or property:
> 
> let a = [0, 1, 2, 3];
> console.log(
> a[Symbol.last] === 3
> /* true */
> );
> 
> There're obviously instances where authors have extended Array prototypes
> with "last" methods or properties, but we can't guarantee they'd all work
> the same. For instance, assume there are some implementations that skip
> undefined values:
> 
> var a = [0, 1, 2, undefined, undefined];
> Array.prototype.last = function(){
> return this[this.length - 1];
> };
> /** One that skips undefined values */
> Array.prototype.last = function(){
> var offset = 1;
> while(offset < this.length && undefined === this[this.length - offset])
> ++offset;
> return this[this.length - offset];
> }
> 
> These discrepancies are subtle, but have the potential to break backwards
> compatibility.
> 
> Using a well-known symbol eliminates the potential for conflict.
> Furthermore, it also offers an opportunity to complement any iterable
> object's ability to synthesise array-like behaviour. For instance, it
> enables iterables to also return the last object in their list of values:
> 
> let pruebas = {
> data: ["Probando", "la", "mierda", "esta", undefined],
> 
> [Symbol.iterator](){
> /* Stuff with .data */
> },
> [Symbol.last](){
> /** Stuff to skip undefined values or whatever */
> let offset = 1;
> let data   = this.data;
> while(
> offset < data.length &&
> undefined === data[data.length - offset]
> )
> ++offset;
> return data[data.length - offset];
> }
> }
> 
> On 23 January 2016 at 08:36, <[email protected]> wrote:
> > Send es-discuss mailing list submissions to
> > 
> >         [email protected]
> > 
> > To subscribe or unsubscribe via the World Wide Web, visit
> > 
> >         https://mail.mozilla.org/listinfo/es-discuss
> > 
> > or, via email, send a message with subject or body 'help' to
> > 
> >         [email protected]
> > 
> > You can reach the person managing the list at
> > 
> >         [email protected]
> > 
> > When replying, please edit your Subject line so it is more specific
> > than "Re: Contents of es-discuss digest..."
> > 
> > Today's Topics:
> >    1. Re: Javascript Language feature Idea (Bradley Meck)
> >    2. Re: Re: Javascript Language feature Idea (Alican ?ubuk?uo?lu)
> >    3. Re: Javascript Language feature Idea (kdex)
> >    4. Re: Javascript Language feature Idea (kdex)
> >    5. Re: Javascript Language feature Idea (Benoit Marchant)
> > 
> > ---------- Forwarded message ----------
> > From: Bradley Meck <[email protected]>
> > To: Dmitry Soshnikov <[email protected]>
> > Cc: es-discuss <[email protected]>
> > Date: Fri, 22 Jan 2016 13:51:54 -0600
> > Subject: Re: Javascript Language feature Idea
> > Personally I prefer a well known symbol for marking you are grabbing from
> > the end of the list rather than this wrapping behavior like D (
> > https://dlang.org/spec/arrays.html#array-length ). That said I think
> > `.last` is more reasonable than changing prototypes.
> > 
> > On Fri, Jan 22, 2016 at 1:17 PM, Dmitry Soshnikov <
> > 
> > [email protected]> wrote:
> >> On Fri, Jan 22, 2016 at 9:53 AM, RacerD123 <[email protected]> wrote:
> >>> In other programming languages such as python, you can specify the last
> >>> element of a list with "list[-1]" but in javascript you have to do
> >>> "list[list.length-1]". Is there maybe a way to make this feature in
> >>> javascript?
> >> 
> >> This could be a good addition, although `slice` may work as well. This
> >> has been discussed previously as well in the last 4-5 years. In addition
> >> with non-enumerable properties you can just monkey-patch
> >> `Array.prototype`
> >> with the `peek` or `last` method. I guess approach when some library
> >> forces
> >> some method to widely used, can be a good candidate for adding it to the
> >> spec (this how it was with `Function.prototype.bind`, e.g., although
> >> today
> >> monkey-patching is a bad practice of course).
> >> 
> >> In addition, you can monkey-patch just `-1`, and other indexes, e.g. a
> >> gist from 5 years old, when a similar topic was proposed here:
> >> https://gist.github.com/DmitrySoshnikov/984921
> >> 
> >> Dmitry
> >> 
> >> _______________________________________________
> >> es-discuss mailing list
> >> [email protected]
> >> https://mail.mozilla.org/listinfo/es-discuss
> > 
> > ---------- Forwarded message ----------
> > From: "Alican Çubukçuoğlu" <[email protected]>
> > To: [email protected]
> > Cc:
> > Date: Fri, 22 Jan 2016 22:32:42 +0200
> > Subject: Re: Re: Javascript Language feature Idea
> > More cool stuff:
> > ```javascript
> > const arr = [1, 2, 3];
> > 
> > // Easy push
> > arr[] = 4; // => arr[arr.length];
> > 
> > // Easy s(p)lice
> > arr[begin, end];,
> > arr[begin,]; // => arr[begin, arr.length];
> > arr[begin, end] = [1, 2, 3];
> > ```
> > 
> > A terrible example (terrible because this should be done with WebGL
> > shaders):
> > ```javascript
> > const image = [ /* Umbagajillion of RGBA pixels */ ];
> > 
> > function manipulate(rgba) {
> > 
> >   rgba[0] += 10;
> >   rgba[1] += 10;
> >   rgba[2] += 10;
> > 
> > }
> > 
> > for (let i = 0; i < image.length / 4; i++) {
> > 
> >   const begin = i * 4;
> >   const end = begin + 4;
> >   
> >   /*
> >   
> >     In case easy s(p)lice doesn't actually Array.p.slice
> >     and just creates a limited view of the array
> >     without breaking reference
> >     (image[begin, end] === image[begin, end])
> >   
> >   */
> >   manipulate(image[begin, end]);
> >   
> >   /*
> >   
> >     In case easy s(p)lice does Array.p.slice
> >     and creates a new array
> >     (image[begin, end] !== image[begin, end])
> >   
> >   */
> >   const pixel = image[begin, end];
> >   manipulate(pixel);
> >   image[begin, end] = pixel;
> > 
> > }
> > ```
> > 
> > 
> > ---------- Forwarded message ----------
> > From: kdex <[email protected]>
> > To: [email protected]
> > Cc:
> > Date: Fri, 22 Jan 2016 22:00:01 +0100
> > Subject: Re: Javascript Language feature Idea
> > I really adore the slicing syntax. Just as a quick fix, though,
> > 
> > > arr[begin,]; // => arr[begin, arr.length];
> > 
> > should obviously return `arr[begin, arr.length - 1]`.
> > 
> > Honestly, I'm not too sure if the "easy push" syntax is particularly self-
> > explanatory. There might be better alternatives.
> > 
> > On Freitag, 22. Januar 2016 22:32:42 CET Alican Çubukçuoğlu wrote:
> > > More cool stuff:
> > > ```javascript
> > > const arr = [1, 2, 3];
> > > 
> > > // Easy push
> > > arr[] = 4; // => arr[arr.length];
> > > 
> > > // Easy s(p)lice
> > > arr[begin, end];,
> > > arr[begin,]; // => arr[begin, arr.length];
> > > arr[begin, end] = [1, 2, 3];
> > > ```
> > > 
> > > A terrible example (terrible because this should be done with WebGL
> > > shaders):
> > > ```javascript
> > > const image = [ /* Umbagajillion of RGBA pixels */ ];
> > > 
> > > function manipulate(rgba) {
> > > 
> > >   rgba[0] += 10;
> > >   rgba[1] += 10;
> > >   rgba[2] += 10;
> > > 
> > > }
> > > 
> > > for (let i = 0; i < image.length / 4; i++) {
> > > 
> > >   const begin = i * 4;
> > >   const end = begin + 4;
> > >   
> > >   /*
> > >   
> > >     In case easy s(p)lice doesn't actually Array.p.slice
> > >     and just creates a limited view of the array
> > >     without breaking reference
> > >     (image[begin, end] === image[begin, end])
> > >   
> > >   */
> > >   manipulate(image[begin, end]);
> > >   
> > >   /*
> > >   
> > >     In case easy s(p)lice does Array.p.slice
> > >     and creates a new array
> > >     (image[begin, end] !== image[begin, end])
> > >   
> > >   */
> > >   const pixel = image[begin, end];
> > >   manipulate(pixel);
> > >   image[begin, end] = pixel;
> > > 
> > > }
> > > ```
> > 
> > ---------- Forwarded message ----------
> > From: kdex <[email protected]>
> > To: [email protected]
> > Cc:
> > Date: Fri, 22 Jan 2016 22:14:20 +0100
> > Subject: Re: Javascript Language feature Idea
> > Standardizing unused array keys breaks compatibility about as much as
> > extending the prototype does, really. Users can already mangle with both.
> > 
> > The problems are a little more subtle, and yes, it would severely break
> > backwards compatibility. Consider this example (accessing an element based
> > on
> > a computed index):
> > 
> > ```js
> > let a = [1, 2, 3];
> > let occurrence = a.indexOf(4);
> > a[occurrence];
> > ```
> > 
> > Currently, this should result in `undefined`. After your proposal, you
> > could
> > introduce a potential bug into every program that accesses arrays using an
> > index computed with `Array.prototype.indexOf`, since it would now return
> > `3`.
> > 
> > On Freitag, 22. Januar 2016 18:59:06 CET Sander Deryckere wrote:
> > > Since Array inherits from Object, it can have any key, including the key
> > > "-1". So something like list[-1] would break compatibility as users can
> > 
> > now
> > 
> > > already assign values to the index -1.
> > > 
> > > If you want a short way to access the last element, it should probably
> > 
> > be a
> > 
> > > function in the Array prototype. Something like list.last().
> > > 
> > > Regards,
> > > Sander
> > > 
> > > 2016-01-22 18:53 GMT+01:00 RacerD123 <[email protected]>:
> > > > In other programming languages such as python, you can specify the
> > > > last
> > > > element of a list with "list[-1]" but in javascript you have to do
> > > > "list[list.length-1]". Is there maybe a way to make this feature in
> > > > javascript?
> > > > 
> > > > _______________________________________________
> > > > es-discuss mailing list
> > > > [email protected]
> > > > https://mail.mozilla.org/listinfo/es-discuss
> > 
> > ---------- Forwarded message ----------
> > From: Benoit Marchant <[email protected]>
> > To: kdex <[email protected]>
> > Cc: [email protected]
> > Date: Fri, 22 Jan 2016 13:35:55 -0800
> > Subject: Re: Javascript Language feature Idea
> > Interesting! More pedestrian, it would be nice to finally have a version
> > of splice that doesn't create a new other Array as a side effect.
> > 
> > > On Jan 22, 2016, at 13:00, kdex <[email protected]> wrote:
> > > 
> > > I really adore the slicing syntax. Just as a quick fix, though,
> > > 
> > >> arr[begin,]; // => arr[begin, arr.length];
> > > 
> > > should obviously return `arr[begin, arr.length - 1]`.
> > > 
> > > Honestly, I'm not too sure if the "easy push" syntax is particularly
> > 
> > self-
> > 
> > > explanatory. There might be better alternatives.
> > > 
> > >> On Freitag, 22. Januar 2016 22:32:42 CET Alican Çubukçuoğlu wrote:
> > >> More cool stuff:
> > >> ```javascript
> > >> const arr = [1, 2, 3];
> > >> 
> > >> // Easy push
> > >> arr[] = 4; // => arr[arr.length];
> > >> 
> > >> // Easy s(p)lice
> > >> arr[begin, end];,
> > >> arr[begin,]; // => arr[begin, arr.length];
> > >> arr[begin, end] = [1, 2, 3];
> > >> ```
> > >> 
> > >> A terrible example (terrible because this should be done with WebGL
> > >> shaders):
> > >> ```javascript
> > >> const image = [ /* Umbagajillion of RGBA pixels */ ];
> > >> 
> > >> function manipulate(rgba) {
> > >> 
> > >>  rgba[0] += 10;
> > >>  rgba[1] += 10;
> > >>  rgba[2] += 10;
> > >> 
> > >> }
> > >> 
> > >> for (let i = 0; i < image.length / 4; i++) {
> > >> 
> > >>  const begin = i * 4;
> > >>  const end = begin + 4;
> > >>  
> > >>  /*
> > >>  
> > >>    In case easy s(p)lice doesn't actually Array.p.slice
> > >>    and just creates a limited view of the array
> > >>    without breaking reference
> > >>    (image[begin, end] === image[begin, end])
> > >>  
> > >>  */
> > >>  manipulate(image[begin, end]);
> > >>  
> > >>  /*
> > >>  
> > >>    In case easy s(p)lice does Array.p.slice
> > >>    and creates a new array
> > >>    (image[begin, end] !== image[begin, end])
> > >>  
> > >>  */
> > >>  const pixel = image[begin, end];
> > >>  manipulate(pixel);
> > >>  image[begin, end] = pixel;
> > >> 
> > >> }
> > >> ```
> > > 
> > > _______________________________________________
> > > es-discuss mailing list
> > > [email protected]
> > > https://mail.mozilla.org/listinfo/es-discuss
> > 
> > _______________________________________________
> > es-discuss mailing list
> > [email protected]
> > https://mail.mozilla.org/listinfo/es-discuss


_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to