Merusak untuk mendapatkan elemen terakhir dari sebuah array di es6

116

Di coffeescript ini langsung:

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

Apakah es6 memungkinkan sesuatu yang serupa?

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

Tentu saja saya bisa melakukannya dengan cara es5 -

const a = b[b.length - 1]

Tapi mungkin ini sedikit rentan terhadap satu kesalahan. Bisakah percikan hanya menjadi hal terakhir dalam penghancuran?

George Simms
sumber
7
Mengapa semua orang berpikir ES6 mengubah segalanya dan ada sintaks baru untuk melakukan xyz?
Felix Kling
23
@FelixKling pertanyaannya secara khusus tentang perilaku ...di es6, terutama bahwa ini hanya dapat digunakan sebagai hal terakhir saat merusak atau dalam daftar parameter. Ini berpotensi berlawanan dengan intuisi seseorang yang masuk ke es6 dari coffeescript dan dengan demikian pertanyaan ini berpotensi berguna.
George Simms
Itu berarti selain [1,2,3].slice(-1)Anda bahkan tidak dapat merusak setara dengan [1,2,3].slice(0, -1). Ini adalah operasi umum. Penghancuran ES6 entah bagaimana adalah lelucon!
scriptum
@Bahkan ada alasan yang sah - untuk menangani iterable yang tak terbatas.
George Simms
Istirahat yang terlalu buruk karena parameter pertama tidak berfungsi. Pasti keren ... Ini jsperf menggunakan beberapa jawaban jsperf.com/destructure-last/1
Shanimal

Jawaban:

46

Tidak mungkin dalam ES6 / 2015. Standar tidak menyediakannya.

Seperti yang Anda lihat di spesifikasi , FormalParameterListbisa berupa:

  • Sebuah FunctionRestParameter
  • a FormalsList(daftar paramet)
  • a FormalsList, diikuti dengan aFunctionRestParameter

Memiliki FunctionRestParameter diikuti oleh parameter tidak disediakan.

Andrey Mikhaylov - lolmaus
sumber
215

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

Ryan Huang
sumber
4
Solusi non-mutatif sederhana yang bagus.
Jack Steam
1
@Shanimal Tergantung, saya mendapatkan popversinya lebih cepat (OS X, Chrome 68).
Dave Newton
1
@ Dave Newton But pop () menyebabkan mutasi
Antonio Pantano
1
@AntonioPantano Ya, salinannya akan dimutasi. Intinya adalah apakah itu lebih cepat atau tidak.
Dave Newton
53

Saya yakin ES6 setidaknya bisa membantu dengan itu:

[...arr].pop()

Mengingat array Anda (arr) tidak terdefinisi dan elemen yang dapat diulang (ya, bahkan string berfungsi !!), ia harus mengembalikan elemen terakhir..bahkan untuk array kosong dan itu juga tidak mengubahnya. Ini membuat array perantara .. tapi itu tidak membutuhkan biaya banyak.

Contoh Anda akan terlihat seperti ini:

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

shoesel
sumber
6
uhh, ini cukup buruk, bahkan .slice(-1)[0]sedikit lebih baik, atau var [last]=arr.slice().reverse()jelek lainnya jika Anda membutuhkan
caub
6
Saya pikir posting ini tentang ES6 / ES2015, bukan? Tapi aku suka terutama bagian terakhirmu. Bagaimana jika menggabungkan keduanya var [last] = arr.slice(-1)
:;
13
cara favorit saya adalahObject.defineProperty(Array.prototype, -1, { get() {return this[this.length - 1] } }); [1,2,3][-1]
caub
3
Meskipun berhasil, itu mutatif dan menghapus item dari larik asli. Tidak ideal dalam banyak skenario.
GavKilbride
4
@GavKilbride tidak. Contohnya sama dengan [].concat(arr).pop();yang tidak bermutasi arr.
Dan
37

Anda dapat merusak susunan terbalik untuk mendekati apa yang Anda inginkan.

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

KamiOfTea
sumber
2
Pintar. Lebih baik dari const last = ['bbb', 'uuu', 'iii'].slice(-1);? Dalam hal pertunjukan?
Vadorequest
1
yang .slice(-1)secara teknis lebih cepat, tetapi tidak memberikan Anda berdua item terakhir DAN subarray dalam satu panggilan, yang merupakan keuntungan dari ...percikan saat destrukturisasi. Hit kinerja pembalikan dua kali harus dipertimbangkan ketika digunakan pada array yang lebih panjang, tetapi untuk skrip kecil mungkin sepadan dengan kenyamanannya? Tapi Anda bisa dengan mudah let a = array.slice(-1), rest = array.slice(0,array.length-2)jika Anda masih menginginkan oneliner di ES5, yaitu ~ 4% lebih cepat. jsperf.com/last-array-splat
mix3d
17

pendekatan lain adalah:

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

Den Kerny
sumber
1
@isakbob yeap, ini dia
Den Kerny
sulit dibaca, atau mungkin hanya otak saya
webjay
mungkin akan sangat membantu menggunakan beberapa alat peraga, jadi ya, itu milik Anda saja, xd xd xd
Den Kerny
5

Belum tentu cara yang paling baik dalam melakukannya. Tetapi tergantung pada konteksnya, cara yang cukup elegan adalah:

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

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

theTaoOfJS
sumber
3
Saya tidak melihat keanggunan dalam solusi ini, tetapi @shoesel sudah mempostingnya
Bergi
2

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

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

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

andrhamm
sumber
2
Ya, saya merasa berguna ketika sudah melakukan perusakan lainnya. Dengan sendirinya tidak semudah membaca solusi klasik.
andrhamm
1

Ini harus bekerja:

const [lastone] = myArray.slice(-1);
OPulido
sumber
1

Anda dapat mencoba retasan ini:

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

Jelas, pertanyaannya adalah tentang Penghancuran untuk Array JavaScript, dan kami tahu tidak mungkin memiliki item terakhir dari Array dengan menggunakan tugas penghancuran, ada cara untuk melakukannya agar tidak dapat diubah , lihat yang berikut ini:

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

Kami tidak mengubah arrvariabel tetapi masih memiliki semua anggota array kecuali item terakhir sebagai array dan memiliki item terakhir secara terpisah.

AmerllicA
sumber
0
let a = [1,2,3]
let [b] = [...a].reverse()
Andrew Nekowitsch
sumber
0

Bukan cara yang merusak tetapi bisa membantu. Menurut dokumentasi javascript dan metode terbalik dapat mencoba ini:

const reversed = array1.reverse();
let last_item = reversed[0]
Pamela Hdz
sumber