Possibility to destructure last item from Array

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

// 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() 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.

1 Like

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

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

I would expect:

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

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

I would expect the same as mhofman.

1 Like

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

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

I agree with this one.

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.

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.

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

1 Like