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?


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.


215

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


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


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


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)


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


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'


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

1

Anda dapat mencoba retasan ini:

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

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.



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]
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.