Proposal: Array.prototype.first() and Array.prototype.last()

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

Proposal: Array.prototype.first() and Array.prototype.last()

Nicu Micleusanu
I propose to standardize `Array.prototype.first()` and
`Array.prototype.last()`, very similar to underscore `_.first()` and
`_.last()`.


A very basic implementation:

```js

Array.prototype.first = function (n) {

     if (!arguments.length) {

         return this[0];

     } else {

         return this.slice(0, Math.max(0, n));

     }

};


Array.prototype.last = function (n) {

     if (!arguments.length) {

         return this[this.length - 1];

     } else {

         return this.slice(Math.max(0, this.length - n));

     }

};

```

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Array.prototype.first() and Array.prototype.last()

Bob Myers
This is well-traveled territory.

Whatever is or is not implemented, interfaces which have optional arguments and return scalars in one case and arrays in another case are a horrible idea. 

To my knowledge no-one has ever explained why the following is a bad idea:

```
array.0
array.-1
```

Bob

On Tue, Sep 27, 2016 at 5:42 PM, Nicu Micleusanu <[hidden email]> wrote:
I propose to standardize `Array.prototype.first()` and `Array.prototype.last()`, very similar to underscore `_.first()` and `_.last()`.


A very basic implementation:

```js

Array.prototype.first = function (n) {

    if (!arguments.length) {

        return this[0];

    } else {

        return this.slice(0, Math.max(0, n));

    }

};


Array.prototype.last = function (n) {

    if (!arguments.length) {

        return this[this.length - 1];

    } else {

        return this.slice(Math.max(0, this.length - n));

    }

};

```

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


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Re: Proposal: Array.prototype.first() and Array.prototype.last()

Nicu Micleusanu
Well, `String.prototype.match()` does this, it returns an array of
matches or `null` in case there are no matches. I agree that in some
situation this can be a source of errors, but the implementation would
be quite useful.

In case it's not acceptable, I would propose read-only members
`Array.prototype.first` and `Array.prototype.last`:

```js
Object.defineProperties(Array.prototype, {
     first: {
         get: function () {
             return this[0];
         }
     },
     last: {
         get: function () {
             if (this.length) {
                 return this[this.length - 1];
             } else {
                 return void 0;
             }
         }
     }
});
```
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Array.prototype.first() and Array.prototype.last()

Jeff Walden-6
In reply to this post by Bob Myers
On 09/27/2016 05:38 AM, Bob Myers wrote:
> To my knowledge no-one has ever explained why the following is a bad idea:
>
> ```
> array.0
> array.-1
> ```

Consider this already-valid code:

  var first = array
  .0.toString();

This parses *right now* as

  var first = array;
  (0.0).toString();

So your proposal would break existing code.  We could imagine inserting a [no LineTerminator here] inside MemberExpression to permit "." NumericLiteral and "." "-" NumericLiteral to appear here, to be sure.  But that's extra complexity, extra ASI-handling (having worked on ASI handling recently, I assure you there's *nothing* simple about it, and further complicating ASI is a strong demerit in my book), all for IMO dubious value.

Jeff
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Array.prototype.first() and Array.prototype.last()

段垚
In reply to this post by Bob Myers

Because `foo.bar` is equivlant to `foo['bar']` in JS so far, and `array.-1` could break this consistency.


On the other hand, `array.first()` seems not necessary because `array[0]` is even more handy; `array.last()` looks fine to me.


If someone prefer a more general solution, I recommand `array.get(n)`:

  * if n >= 0 && n < array.length: equivlant to array[n]
  * if n < 0 && -n < array.length: equivlant to array[array.length + n]
  * if n <= -array.length || n >= array.length: throw or return undefined
  * if n is not a integer or not a number: throw or return undefined

The last 2 rules make `array.get(n)` less error prone than `array[n]`. I prefer throwing, but maybe returning undefined is more JS-style?

在 2016/9/27 20:38, Bob Myers 写道:
This is well-traveled territory.

Whatever is or is not implemented, interfaces which have optional arguments and return scalars in one case and arrays in another case are a horrible idea. 

To my knowledge no-one has ever explained why the following is a bad idea:

```
array.0
array.-1
```

Bob

On Tue, Sep 27, 2016 at 5:42 PM, Nicu Micleusanu <[hidden email]> wrote:
I propose to standardize `Array.prototype.first()` and `Array.prototype.last()`, very similar to underscore `_.first()` and `_.last()`.


A very basic implementation:

```js

Array.prototype.first = function (n) {

    if (!arguments.length) {

        return this[0];

    } else {

        return this.slice(0, Math.max(0, n));

    }

};


Array.prototype.last = function (n) {

    if (!arguments.length) {

        return this[this.length - 1];

    } else {

        return this.slice(Math.max(0, this.length - n));

    }

};

```

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



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


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Array.prototype.first() and Array.prototype.last()

Claude Pache

Le 28 sept. 2016 à 07:38, 段垚 <[hidden email]> a écrit :

Because `foo.bar` is equivlant to `foo['bar']` in JS so far, and `array.-1` could break this consistency.


On the other hand, `array.first()` seems not necessary because `array[0]` is even more handy; `array.last()` looks fine to me.


If someone prefer a more general solution, I recommand `array.get(n)`:

  * if n >= 0 && n < array.length: equivlant to array[n]
  * if n < 0 && -n < array.length: equivlant to array[array.length + n]
  * if n <= -array.length || n >= array.length: throw or return undefined
  * if n is not a integer or not a number: throw or return undefined

The last 2 rules make `array.get(n)` less error prone than `array[n]`. I prefer throwing, but maybe returning undefined is more JS-style?

For consistency with the rest of the builtin library, `array.get(n)` should be equivalent to `array.slice(n)[0]`, which means: convert `n` to an integer, and: return `undefined` for out-of-bound index.

—Claude


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Proposal: Array.prototype.first() and Array.prototype.last()

段垚

在 2016/9/28 14:42, Claude Pache 写道:


Le 28 sept. 2016 à 07:38, 段垚 <[hidden email]> a écrit :

Because `foo.bar` is equivlant to `foo['bar']` in JS so far, and `array.-1` could break this consistency.


On the other hand, `array.first()` seems not necessary because `array[0]` is even more handy; `array.last()` looks fine to me.


If someone prefer a more general solution, I recommand `array.get(n)`:

  * if n >= 0 && n < array.length: equivlant to array[n]
  * if n < 0 && -n < array.length: equivlant to array[array.length + n]
  * if n <= -array.length || n >= array.length: throw or return undefined
  * if n is not a integer or not a number: throw or return undefined

The last 2 rules make `array.get(n)` less error prone than `array[n]`. I prefer throwing, but maybe returning undefined is more JS-style?

For consistency with the rest of the builtin library, `array.get(n)` should be equivalent to `array.slice(n)[0]`, which means: convert `n` to an integer, and: return `undefined` for out-of-bound index.
I regard such converting behavior a bad legacy of JS, and want to avoid it in new APIs.


—Claude



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