# Possibility to destructure last item from Array

**URL:** <https://es.discourse.group/t/possibility-to-destructure-last-item-from-array/1128>\
**Category:** 💡 Ideas\
**Created:** [December 20, 2021, 9:43pm UTC](https://es.discourse.group/t/possibility-to-destructure-last-item-from-array/1128 "2021-12-20T21:43:38Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![DoctypeRosenthal](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/doctyperosenthal/32/1160_2.png) [@DoctypeRosenthal](https://es.discourse.group/u/DoctypeRosenthal)\
**Post date:** [December 20, 2021, 9:43pm UTC](https://es.discourse.group/t/possibility-to-destructure-last-item-from-array/1128/1 "2021-12-20T21:43:38Z")

</div>

My suggestion is a new possibility to destructure the last item from Arrays/Function parameters like so:

```javascript
// ARRAYS:

const [first, ...rest] = [1,2,3,4] 
// first = 1, rest = [2,3,4], works as usual!

const [first, ...rest, last] = [1,2,3,4] 
// -> first = 1, rest = [2,3], last = 4

const [...rest, last] = [1,2,3,4] 
// rest = [1,2,3], last = 4

const [...rest, last] = [1,2] 
// rest = [1], last = 2

const [...rest, last] = [1] 
// rest = [1], last = 1

const [first, ...rest, last] = [1] 
// first = 1, rest = [1], last = 1

const [...rest, last] = [] 
// rest = [], last = undefined

// FUNCTION PARAMS:

const a = (first, ...rest, last) => last

a(1) // -> undefined
a(1,2) // -> undefined
a(1,2,3) // -> 3
a(1,2,3,4) // -> 4
// etc.

```

It would be rather helpful in many situations I come across frequently. At the time of writing, lodash's [`last()`](https://lodash.com/docs#last) function tries to do that.

What do you think?

Kind regards,  
Lorenz

EDIT:  
I see this idea is already being worked on: [GitHub - tc39/proposal-deiter: Double-Ended Iterator and Destructuring](https://github.com/tc39/proposal-deiter).

---

<div class="post-metadata">

**Author:** ![bergus](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/bergus/32/152_2.png) [@bergus](https://es.discourse.group/u/bergus)\
**Post date:** [December 20, 2021, 11:05pm UTC](https://es.discourse.group/t/possibility-to-destructure-last-item-from-array/1128/2 "2021-12-20T23:05:25Z")

</div>

See also [GitHub - tc39/proposal-array-last: A JavaScript TC39 Proposal for getting the last element from an array](https://github.com/tc39/proposal-array-last) and [GitHub - tc39/proposal-relative-indexing-method: A TC39 proposal to add an .at() method to all the basic indexable classes (Array, String, TypedArray)](https://github.com/tc39/proposal-relative-indexing-method)

---

<div class="post-metadata">

**Author:** ![mhofman](https://avatars.discourse-cdn.com/v4/letter/m/f14d63/32.png) [@mhofman](https://es.discourse.group/u/mhofman)\
**Post date:** [December 20, 2021, 11:13pm UTC](https://es.discourse.group/t/possibility-to-destructure-last-item-from-array/1128/3 "2021-12-20T23:13:15Z")

</div>

> [@DoctypeRosenthal](#):
>
> ```javascript
> const [...rest, last] = [1] 
> // rest = [1], last = 1
> 
> const [first, ...rest, last] = [1] 
> // first = 1, rest = [1], last = 1
> 
> ```

These 2 are the most surprising to me. Why should `...` behave that way?

I would expect:

```javascript
const [...rest, last] = [1] 
// rest = [], last = 1

const [first, ...rest, last] = [1] 
// first = 1, rest = [], last = undefined

```

---

<div class="post-metadata">

**Author:** ![ljharb](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/ljharb/32/8_2.png) [@ljharb](https://es.discourse.group/u/ljharb)\
**Post date:** [December 20, 2021, 11:26pm UTC](https://es.discourse.group/t/possibility-to-destructure-last-item-from-array/1128/4 "2021-12-20T23:26:06Z")

</div>

I would expect the same as mhofman.

---

<div class="post-metadata">

**Author:** ![claudiameadows](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/claudiameadows/32/126_2.png) [@claudiameadows](https://es.discourse.group/u/claudiameadows)\
**Post date:** [December 21, 2021, 12:53am UTC](https://es.discourse.group/t/possibility-to-destructure-last-item-from-array/1128/5 "2021-12-21T00:53:00Z")

</div>

The semantics you expect are what I'd prefer, too. But aside from that, I extremely want this.

---

<div class="post-metadata">

**Author:** ![DoctypeRosenthal](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/doctyperosenthal/32/1160_2.png) [@DoctypeRosenthal](https://es.discourse.group/u/DoctypeRosenthal)\
**Post date:** [December 22, 2021, 5:33pm UTC](https://es.discourse.group/t/possibility-to-destructure-last-item-from-array/1128/6 "2021-12-22T17:33:53Z")

</div>

```javascript
const [first, ...rest, last] = [1] 
// first = 1, rest = [], last = undefined

```

I agree with this one.

```javascript
const [...rest, last] = [1] 
// rest = [], last = 1

```

not with this one as by the logic you talked about everything is destructured FIFO/greedily. So rest = [1], last = undefined.

---

<div class="post-metadata">

**Author:** ![mhofman](https://avatars.discourse-cdn.com/v4/letter/m/f14d63/32.png) [@mhofman](https://es.discourse.group/u/mhofman)\
**Post date:** [December 22, 2021, 6:48pm UTC](https://es.discourse.group/t/possibility-to-destructure-last-item-from-array/1128/7 "2021-12-22T18:48:22Z")

</div>

No, my intuition is that fixed identifiers consume elements from both the head and the tail (with precedence to the head), and the `...` captures the rest, aka anything that wasn't consumed as fixed elements.

> [@DoctypeRosenthal](#):
>
> `a(1,2) // -> undefined`

I just noticed this is also wrong, and I would expect `a(1,2) // -> 2`

---

<div class="post-metadata">

**Author:** ![yukulele](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/yukulele/32/1519_2.png) [@yukulele](https://es.discourse.group/u/yukulele)\
**Post date:** [October 18, 2022, 12:45pm UTC](https://es.discourse.group/t/possibility-to-destructure-last-item-from-array/1128/8 "2022-10-18T12:45:32Z")

</div>

I think the destructuring should be done this way:

- get each param before rest
- get each param after rest in REVERSE order
- get rest

Examples:

(1)

```javascript
const [a, b, c, ...rest, x, y, z] = [1, 2, 3, 4, 5, 6, 7, 8, 9] 

// before rest
a = 1, b = 2, c = 3

// after rest
x = 7, y = 8, z = 9

// rest
rest = [4, 5, 6]

```

(2)

```javascript
const [a, b, c, ...rest, x, y, z] = [1, 2, 3, 4, 5, 6] 

// before rest
a = 1, b = 2, c = 3

// after rest
x = 4, y = 5, z = 6

// rest
rest = []

```

(3)

```javascript
const [a, b, c, ...rest, x, y, z] = [1, 2, 3, 4, 5] 

// before rest
a = 1, b = 2, c = 3

// after rest
x = undefined, y = 4, z = 5

// rest
rest = []

```

(4)

```javascript
const [a, b, c, ...rest, x, y, z] = [1, 2] 

// before rest
a = 1, b = 2, c = undefined

// after rest
x = undefined, y = undefined, z = undefined

// rest
rest = []

```

In others words, this function:

```javascript
function(a, b, c, ...rest, x, y, z) {
  console.log(a, b, c, rest, x, y, z)
}

```

is equivalent to this one:

```javascript
function(...args) {
  var a = args.shift()
  var b = args.shift()
  var c = args.shift()

  var z = args.pop()
  var y = args.pop()
  var x = args.pop()

  const rest = args

  console.log(a, b, c, rest, x, y, z)
}

```

---

<div class="post-metadata">

**Author:** ![conartist6](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/conartist6/32/515_2.png) [@conartist6](https://es.discourse.group/u/conartist6)\
**Post date:** [November 27, 2022, 4:26am UTC](https://es.discourse.group/t/possibility-to-destructure-last-item-from-array/1128/9 "2022-11-27T04:26:32Z")

</div>

If anyone wants to mock up the logic I've already built most of it as part of my [iterable slice implementation](https://github.com/iter-tools/iter-tools/blob/e87a3db1d8c1724f5c29e51675b5ce6701ff6321/src/impls/%24slice/slice.js), which needs it to be able to understand negative end indicies.

---

<div class="post-metadata">

**Author:** ![PlanckItDev](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/planckitdev/32/2046_2.png) [@PlanckItDev](https://es.discourse.group/u/PlanckItDev)\
**Post date:** [March 31, 2024, 12:36am UTC](https://es.discourse.group/t/possibility-to-destructure-last-item-from-array/1128/11 "2024-03-31T00:36:12Z")

</div>

Chat GPT: JavaScript doesn't support an inverse rest operator like `(...a, b)` to spread elements into arguments while also having a trailing argument outside of the spread.

However, you can achieve similar behavior using array destructuring and the spread operator in combination with regular function arguments.

Here's an example of how you might accomplish this:

```javascript
function myFunction(a, b, ...c) {
    console.log(a, b, c);
}

const arr = [1, 2, 3, 4, 5];

myFunction(...arr.slice(0, -1), arr[arr.length - 1]);

```

---

<div class="post-metadata">

**Author:** ![PlanckItDev](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/planckitdev/32/2046_2.png) [@PlanckItDev](https://es.discourse.group/u/PlanckItDev)\
**Post date:** [March 31, 2024, 12:46am UTC](https://es.discourse.group/t/possibility-to-destructure-last-item-from-array/1128/12 "2024-03-31T00:46:51Z")

</div>

Need this for reflections and meta prog
