es6에서 배열의 마지막 요소를 얻기위한 구조 해제


116

coffeescript에서 이것은 간단합니다.

coffee> a = ['a', 'b', 'program']
[ 'a', 'b', 'program' ]
coffee> [_..., b] = a
[ 'a', 'b', 'program' ]
coffee> b
'program'

es6는 비슷한 것을 허용합니까?

> 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)                                           

물론 es5 방식으로 할 수 있습니다.

const a = b[b.length - 1]

그러나 아마도 이것은 하나의 오류로 인해 약간 벗어나기 쉽습니다. 표시가 구조 해체의 마지막 일뿐일까요?


7
왜 모두가 ES6이 모든 것을 바꾸고 xyz를 수행하기위한 새로운 구문이 있다고 생각합니까?
Felix Kling

23
@FelixKling 질문은 특히 ...es6 의 동작에 관한 것입니다. 특히 구조화 또는 매개 변수 목록에서 마지막으로 만 사용할 수 있습니다. 이것은 coffeescript에서 es6로 들어오는 누군가에게는 잠재적으로 반 직관적이기 때문에이 질문은 잠재적으로 유용합니다.
George Simms 2015 년

그 수단 외에 [1,2,3].slice(-1)당신도에 해당 destructure 수 없습니다 [1,2,3].slice(0, -1). 이것은 일반적인 작업입니다. ES6 구조화는 어떻게 든 농담입니다!
scriptum

@Iven에는 정당한 이유가 있습니다-무한 반복 가능을 처리하는 것입니다.
George Simms 2016 년

첫 번째 매개 변수가 작동하지 않아 휴식이 너무 심합니다. 멋 졌을 텐데 ... 여기에 답변 중 일부를 사용하는 jsperf가 있습니다. jsperf.com/destructure-last/1
Shanimal

답변:


46

ES6 / 2015에서는 불가능합니다. 표준은 그것을 제공하지 않습니다.

당신이 볼 수 있듯이 사양 의가 FormalParameterList될 수 있습니다 :

  • FunctionRestParameter
  • a FormalsList(매개 변수 목록)
  • a FormalsList다음에 aFunctionRestParameter

FunctionRestParameter파라미터 뒤에 제공되지 않는다.


215

console.log('last', [1, 3, 4, 5].slice(-1));
console.log('second_to_last', [1, 3, 4, 5].slice(-2));


4
멋지고 단순한 비 돌연변이 솔루션.
Jack Steam

1
@Shanimal에 따라 pop버전이 더 빨라지고 있습니다 (OS X, Chrome 68).
Dave Newton

1
@ 데이브 뉴턴 그러나 팝업 () 원인 돌연변이
안토니오 Pantano는

1
@AntonioPantano 예, 복사본을 변경합니다. 포인트는 더 빠른지 여부가 주어지지 않았습니다.
Dave Newton

53

나는 ES6가 적어도 도움이 될 수 있다고 믿습니다.

[...arr].pop()

배열 (arr)이 정의되지 않고 반복 가능한 요소 (예, 문자열도 작동합니다 !!)가 주어지면 빈 배열에 대해서도 마지막 요소를 반환해야하며 변경하지도 않습니다. 그래도 중간 배열을 생성하지만 비용이 많이 들지는 않습니다.

귀하의 예는 다음과 같습니다.

  console.log(  [...['a', 'b', 'program']].pop() );


6
으음, 심지어는 아주 나쁜 .slice(-1)[0]가 두드러 덜 나쁜있다, 또는 var [last]=arr.slice().reverse()당신이 필요로하는 경우 다른 추한 하나입니다
caub

6
이 게시물이 ES6 / ES2015에 관한 것이라고 생각했습니다. 하지만 특히 마지막 작품이 마음에 듭니다. 두 가지를 결합하는 방법 : var [last] = arr.slice(-1);)
shoesel

13
내가 가장 좋아하는 방법은Object.defineProperty(Array.prototype, -1, { get() {return this[this.length - 1] } }); [1,2,3][-1]
caub

3
이것이 작동하지만 그것은 돌연변이이며 원래 배열에서 항목을 제거합니다. 많은 시나리오에서 이상적이지 않습니다.
GavKilbride 2017

4
@GavKilbride 그렇지 않습니다. 예제는 [].concat(arr).pop();mutate하지 않는 것과 동일 arr합니다.
Dan

37

역 배열을 분해하여 원하는 것에 근접 할 수 있습니다.

const [a, ...rest] = ['a', 'b', 'program'].reverse();
  
document.body.innerHTML = 
    "<pre>"
    + "a: " + JSON.stringify(a) + "\n\n"
    + "rest: " + JSON.stringify(rest.reverse())
    + "</pre>";


2
똑똑한. 보다 낫다 const last = ['bbb', 'uuu', 'iii'].slice(-1);? 공연 측면에서?
Vadorequest

1
.slice(-1)기술적으로 빠르지 만 그것은 당신에게 마지막 항목과의 이익을 하나 전화에있는 부분 배열을 모두 제공하지 않습니다 ...destructuring 때 플랫을. 더 긴 배열에서 사용할 때 반전의 성능 저하를 두 번 고려해야하지만 작은 스크립트의 경우 아마도 편리 할 가치가 있습니까? 하지만 let a = array.slice(-1), rest = array.slice(0,array.length-2)ES5에서 원 라이너를 원하면 약 4 % 더 빠릅니다. jsperf.com/last-array-splat
mix3d

17

또 다른 접근 방식은 다음과 같습니다.

const arr = [1, 2, 3, 4, 5]
const { length, [length - 1]: last } = arr; //should be 5
console.log(last)


1
엡 @isakbob, 여기 당신은
덴 Kerny

읽기 어렵거나 아마도 그것은 내 두뇌 일 것입니다
webjay

여러 소품을 사용하는 것이 매우 도움이 될 수 있습니다. 그렇습니다. xd xd xd
Den Kerny

5

반드시 가장 성능이 좋은 방법은 아닙니다. 그러나 상황에 따라 매우 우아한 방법은 다음과 같습니다.

const myArray = ['one', 'two', 'three'];
const theOneIWant = [...myArray].pop();

console.log(theOneIWant); // 'three'
console.log(myArray.length); //3


3
나는이 솔루션에서 어떤 우아함도 보지 못했지만 어쨌든 @shoesel은 이미 그것을 게시했습니다
Bergi

2

const arr = ['a', 'b', 'c']; // => [ 'a', 'b', 'c' ]

const {
  [arr.length - 1]: last
} = arr;

console.log(last); // => 'c'


2
예, 이미 다른 디스트 럭처링을 할 때 유용합니다. 그 자체로는 고전적인 솔루션만큼 읽기 쉽지 않습니다.
andrhamm


1

이 해킹을 시도해 볼 수 있습니다.

let a = ['a', 'b', 'program'];
let [last] = a.reverse();
a.reverse();
console.log(last);

0

확실히 문제는 JavaScript Arrays의 Destructuring 에 관한 것이며, Destructuring 할당을 사용하여 Array의 마지막 항목을 가질 수 없다는 것을 알고 있습니다. 불변 하는 방법이 있습니다. 다음을 참조하십시오.

const arr = ['a', 'b', 'c', 'last'];

~~~
const arrDepth = arr.length - 1;

const allExceptTheLast = arr.filter( (dep, index) => index !== arrDepth && dep );
const [ theLastItem ] = arr.filter( (dep, index) => index === arrDepth && dep );

우리는 arr변수를 변경하지 않지만 마지막 항목을 제외한 모든 배열 구성원을 배열로 갖고 마지막 항목을 별도로 가지고 있습니다.



0

방법을 파괴하지는 않지만 도움이 될 수 있습니다. 자바 스크립트 문서 및 반대 방법에 따르면 다음을 시도 할 수 있습니다.

const reversed = array1.reverse();
let last_item = reversed[0]
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.