Destructuring to get the last element of an array in es6
Ecmascript 6DestructuringEcmascript 6 Problem Overview
In coffeescript this is straightforward:
coffee> a = ['a', 'b', 'program']
[ 'a', 'b', 'program' ]
coffee> [_..., b] = a
[ 'a', 'b', 'program' ]
coffee> b
'program'
Does es6 allow for something similar?
> const [, b] = [1, 2, 3]
'use strict'
> b // it got the second element, not the last one!
2
> const [...butLast, last] = [1, 2, 3]
SyntaxError: repl: Unexpected token (1:17)
> 1 | const [...butLast, last] = [1, 2, 3]
| ^
at Parser.pp.raise (C:\Users\user\AppData\Roaming\npm\node_modules\babel\node_modules\babel-core\node_modules\babylon\lib\parser\location.js:24:13)
Of course I can do it the es5 way -
const a = b[b.length - 1]
But maybe this is a bit prone to off by one errors. Can the splat only be the last thing in the destructuring?
Ecmascript 6 Solutions
Solution 1 - Ecmascript 6
console.log('last', [1, 3, 4, 5].slice(-1));
console.log('second_to_last', [1, 3, 4, 5].slice(-2));
Solution 2 - Ecmascript 6
I believe ES6 could at least help with that:
[...arr].pop()
Given your array (arr) is not undefined and an iterable element (yes, even strings work!!), it should return the last element..even for the empty array and it doesn't alter it either. It creates an intermediate array though..but that should not cost much.
Your example would then look like this:
console.log( [...['a', 'b', 'program']].pop() );
Solution 3 - Ecmascript 6
It is not possible in ES6/2015. The standard just doesn't provide for it.
As you can see in the spec, the FormalParameterList
can either be:
- a
FunctionRestParameter
- a
FormalsList
(a list of parametes) - a
FormalsList
, followed by aFunctionRestParameter
Having FunctionRestParameter
followed by parameters is not provided.
Solution 4 - Ecmascript 6
You can destructure the reversed array to get close to what you want.
const [a, ...rest] = ['a', 'b', 'program'].reverse();
document.body.innerHTML =
"<pre>"
+ "a: " + JSON.stringify(a) + "\n\n"
+ "rest: " + JSON.stringify(rest.reverse())
+ "</pre>";
Solution 5 - Ecmascript 6
another approach is:
const arr = [1, 2, 3, 4, 5]
const { length, [length - 1]: last } = arr; //should be 5
console.log(last)
Solution 6 - Ecmascript 6
Not necessarily the most performant way of doing. But depending on the context a quite elegant way would be:
const myArray = ['one', 'two', 'three'];
const theOneIWant = [...myArray].pop();
console.log(theOneIWant); // 'three'
console.log(myArray.length); //3
Solution 7 - Ecmascript 6
Getting the last element of the array:
const [last,] = ['a', 'b', 'program'].reverse();
Solution 8 - Ecmascript 6
const arr = ['a', 'b', 'c']; // => [ 'a', 'b', 'c' ]
const {
[arr.length - 1]: last
} = arr;
console.log(last); // => 'c'
Solution 9 - Ecmascript 6
This should work:
const [lastone] = myArray.slice(-1);
Solution 10 - Ecmascript 6
Not destructing way but could help. According to javascript documentation and reverse method could be try this:
const reversed = array1.reverse();
let last_item = reversed[0]
Solution 11 - Ecmascript 6
You could further destruct array´s ...rest
array as Object
, in order to get its length
prop and build a computed prop name for the last index.
This even works for parameter destruction:
const a = [1, 2, 3, 4];
// Destruct from array ---------------------------
const [A_first, ...{length: l, [l - 1]: A_Last}] = a;
console.log('A: first: %o; last: %o', A_first, A_Last); // A: first: 1; last: 4
// Destruct from fn param(s) ---------------------
const fn = ([B_first, ...{length: l, [l - 1]: B_Last}]) => {
console.log('B: first: %o; last: %o', B_first, B_Last); // B: first: 1; last: 4
};
fn(a);
Solution 12 - Ecmascript 6
You can try using object destructuring applied to an array to extract the length
and then get last item: e.g.:
const { length, 0: first, [length - 1]: last } = ['a', 'b', 'c', 'd']
// length = 4
// first = 'a'
// last = 'd'
UPDATE
Another approach Array.prototype.at()
> The at() method takes an integer value and returns the item at that index, allowing for positive and negative integers...
const last = ['a', 'b', 'c', 'd'].at(-1)
// 'd'
Solution 13 - Ecmascript 6
let a = [1,2,3]
let [b] = [...a].reverse()
Solution 14 - Ecmascript 6
You can try this hack:
let a = ['a', 'b', 'program'];
let [last] = a.reverse();
a.reverse();
console.log(last);
Solution 15 - Ecmascript 6
Definitely, the question is about Destructuring for JavaScript Arrays, and we know it is not possible to have the last item of an Array by using the destructuring assignment, there is a way to do it immutable, see the following:
const arr = ['a', 'b', 'c', 'last'];
~~~
const arrLength = arr.length - 1;
const allExceptTheLast = arr.filter( (_, index) => index !== arrLength );
const [ theLastItem ] = arr.filter( (_, index) => index === arrLength );
We do not mutate the arr
variable but still have all the array members except the last item as an array and have the last item separately.
Solution 16 - Ecmascript 6
Using array deconstructing: "capturing" the array
, "splice
d" array (arrMinusEnd
), and "pop
ed"/"slice
d" element (endItem
).
var [array, arrMinusEnd, endItem] =
["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"]
.reduce(
(acc, cv, idx, arr) => {
if(idx<arr.length-1) acc[1].push(cv);
else {
acc[0]=arr;
acc[2]=cv;
};
return acc;
},
[null,[],[]]
)
;
console.log("array=");
console.log(array);
console.log("arrMinusEnd=");
console.log(arrMinusEnd);
console.log("endItem=\""+endItem+"\"");
.as-console-wrapper { max-height: 100% !important; top: 0; }