3

I just discovered the delightful ES6 destructuring syntax for lists, i.e.

ls = [1, 2, 3]

[first, ...rest] = ls

which sets first to 1 and rest to [2,3]. However, is it possible to split the list into rest=[1,2] and last=3 using similar syntax?

I didn't have any luck googling it. I tried some obvious guesses for such a syntax (see below), but they all produced syntax errors.

[rest..., last] = ls
[...rest, last] = ls

I suppose I could do it by reversing the list twice, so an alternate solution to my question would be a constant time list reversal function.

Alex
  • 257
  • 3
  • 9
  • 2
    `...rest` means remaining values. And since you are using it for first argument, it will assign everything there. A simple way to achieve is `var rest = ls.slice(0); var last = rest.pop()` – Rajesh Jun 01 '17 at 13:43
  • All elements except the last one are often called `init`, btw. –  Jun 01 '17 at 14:20

2 Answers2

8

What is commonly called "array destructuring" is actually destructuring an iterable, of which an array is a special case. The thing about iterables is that they can be infinite, or "lazy". That is the reason that you cannot destructure into some arbitrary number of elements followed by the last one:

const [...first, last] = integers();

because integers could be

function* integers() {
  let n = 0;
  while (true) yield n++;
}

and then what would last be?

  • 1
    It should be called iterable destructuring from the beginning. Good explanation! –  Jun 01 '17 at 14:25
  • 1
    There's no theoretical problem with a fixed number of assignment targets after the array pattern. Notice that an infinite iterable never terminates destructuring even with a rest pattern, as it does not lazily initialise `rest` with an iterable but does strictly fill an array. – Bergi Jun 01 '17 at 15:16
-1

No, this only works on trailing array elements. So, as you said, they way to achieve what you want would be reversing the array first.

Just in case you haven't come across a similar pattern for object, there is one:

const {a, ...rest} = {a: "prop1", b: "prop2", c: "prop3"}

A great tool to try all this new features out is https://babeljs.io/repl

m1kael
  • 2,801
  • 1
  • 15
  • 14