@Thomas: I think your implementation has a bug for negative values of n. It 
should have been `+ n` instead of `-n`, probably.

To me, It would feel a little more "natural" if it behaved somewhere around 
this:

```js
/* Used like the [] operator, but indices are counted from right to left and 
also works with negative numbers */
Array.prototype.last = function(n) {
        if (n === undefined) {
                n = 0;
        }
        else if (typeof n !== "number") {
                throw new Error("First argument must be a number");
        }
        if (n < 0) {
                return this[Math.abs(n) - 1];
        }
        return this[this.length - 1 - n];
};
/* Used like the [] operator, but also works with negative numbers */
Array.prototype.nth = function(n) {
        if (n === undefined) {
                n = 0;
        }
        else if (typeof n !== "number") {
                throw new Error("First argument must be a number");
        }
        if (n < 0) {
                return this.last(Math.abs(n) - 1);
        }
        else {
                return this[n];
        }
};
[1, 2, 3].last();     // 3
[1, 2, 3].last(0);    // 3
[1, 2, 3].last(1);    // 2
[1, 2, 3].last(2);    // 1
[1, 2, 3].last(3);    // undefined
[1, 2, 3].last(-1);   // 1
[1, 2, 3].last(-2);   // 2
[1, 2, 3].last(-3);   // 3
[1, 2, 3].nth();      // 1
[1, 2, 3].nth(0);     // 1
[1, 2, 3].nth(1);     // 2
[1, 2, 3].nth(-1);    // 3
[1, 2, 3].nth(-4);    // undefined
[1, 2, 3].nth(null);  // error
[1, 2, 3].last(null); // error
```

On Samstag, 23. Januar 2016 16:51:21 CET Thomas wrote:
> Is this what you're thinking?
> 
> Array.prototype.nth = function (n){
>   if(n < 0){
>     return this[this.length -n];
>   } else {
>     return this[n];
>   }
> }
> 
> Thomas Foster
> 
> @thomasfoster96
> Ph: +61477808008
> http://thomasfoster.co/
> 
> > On 23 Jan 2016, at 4:40 PM, kdex <[email protected]> wrote:
> > 
> > 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];
> >> }
> >> }
> >> 
> >> O


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

Reply via email to