Es6'daki bir dizinin son öğesini elde etmek için yıkım


116

Kahve kağıdında bu basittir:

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

Es6 benzer bir şeye izin veriyor mu?

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

Tabii ki es5 yolu ile yapabilirim -

const a = b[b.length - 1]

Ama belki bu, bir hatayla biraz kapanabilir. Sıçrama sadece yıkımdaki son şey olabilir mi?


7
Neden herkes ES6'nın her şeyi değiştirdiğini düşünüyor ve xyz yapmak için bazı yeni sözdizimi var?
Felix Kling

23
@FelixKling soru özellikle ...es6'nın davranışı ile ilgili , özellikle de yıkarken veya bir parametre listesinde sadece son şey olarak kullanılabileceği. Bu, kahve kitabından es6'ya gelen biri için potansiyel olarak mantıksızdır ve bu nedenle bu soru potansiyel olarak yararlıdır.
George Simms

Bu demek oluyor ki, [1,2,3].slice(-1)sizden başka eşdeğer bir yıkım bile yapamazsınız [1,2,3].slice(0, -1). Bunlar yaygın işlemlerdir. ES6 yıkımı bir şekilde şaka!
scriptum

@ Meşru bir neden olsa bile - sonsuz yinelemeleri işlemek için.
George Simms

İlk parametre çalışmadığı için dinlenme çok kötü. Harika olurdu ... İşte bazı cevapları kullanan bir jsperf jsperf.com/destructure-last/1
Shanimal

Yanıtlar:


46

ES6 / 2015'te mümkün değildir. Standart bunu sağlamaz.

Spesifikasyonda görebileceğiniz gibi , şunlardan biri FormalParameterListolabilir:

  • bir FunctionRestParameter
  • a FormalsList(bir parametre listesi)
  • a FormalsList, ardından aFunctionRestParameter

Sonra FunctionRestParameterparametreleri takip sağlanmaz.


215

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


4
Güzel, basit, değişmeyen bir çözüm.
Jack Steam

1
@Shanimal Bağlı, popsürümü daha hızlı alıyorum (OS X, Chrome 68).
Dave Newton

1
@Dave Newton Ama pop () mutasyona neden olur
Antonio Pantano

1
@AntonioPantano Evet, kopyayı değiştirir. Önemli olan nokta, daha hızlı olup olmadığıdır.
Dave Newton

53

ES6'nın en azından bu konuda yardımcı olabileceğine inanıyorum:

[...arr].pop()

Diziniz (dizi) tanımsız olmadığı ve yinelenebilir bir öğe olduğu (evet, dizeler bile çalışır !!) göz önüne alındığında, boş dizi için bile son öğeyi döndürmelidir ve onu da değiştirmez. Yine de bir ara dizi yaratır ... ama bu çok maliyetli olmamalı.

Örneğiniz daha sonra şöyle görünecektir:

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


6
uhh, bu oldukça kötü, hatta .slice(-1)[0]biraz daha az kötü, ya var [last]=arr.slice().reverse()da ihtiyacınız varsa başka bir çirkin
caub

6
Bu yazının ES6 / ES2015 hakkında olduğunu sanıyordum, değil mi? Ama özellikle son parçanı beğendim. var [last] = arr.slice(-1)
İkisini

13
en sevdiğim yolObject.defineProperty(Array.prototype, -1, { get() {return this[this.length - 1] } }); [1,2,3][-1]
caub

3
Bu işe yarasa da, mutatiftir ve öğeyi orijinal diziden kaldırır. Pek çok senaryoda ideal değil.
GavKilbride

4
@GavKilbride değil. Örnek, [].concat(arr).pop();mutasyona uğramayanla aynıdır arr.
Dan

37

İstediğiniz şeye yaklaşmak için ters çevrilmiş diziyi yok edebilirsiniz.

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


2
Akıllı. Daha const last = ['bbb', 'uuu', 'iii'].slice(-1);mı iyi ? Performanslar açısından?
Vadorequest

1
.slice(-1)teknik olarak daha hızlıdır ama size son öğeyi VE bir faydadır bir çağrıda, içinde SubArray hem vermez ...kurucuların zaman uyarısı. Daha uzun dizilerde kullanıldığında iki kez tersine çevirmenin performans etkisi dikkate alınmalıdır, ancak küçük bir komut dosyası için muhtemelen rahatlığa değer mi? Ama let a = array.slice(-1), rest = array.slice(0,array.length-2)yine de ES5'teki oneliner'ı istiyorsanız, bu da ~% 4 daha hızlıdır. jsperf.com/last-array-splat
mix3d

17

başka bir yaklaşım şudur:

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


1
@isakbob evet, işte buradasınız
Den Kerny

okumak zor, ya da belki de sadece beynim
webjay

birden fazla sahne kullanmak çok yararlı olabilir, bu yüzden evet, sadece sizin, xd xd xd
Den Kerny

5

Yapmanın en performanslı yolu bu olmayabilir. Ancak bağlama bağlı olarak oldukça zarif bir yol şöyle olabilir:

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

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


3
Bu çözümde herhangi bir zarafet görmüyorum, ancak yine de @shoesel bunu zaten yayınladı
Bergi

2

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

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

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


2
Evet, halihazırda başka yıkıcı işler yaparken faydalı buluyorum. Tek başına, klasik çözüm kadar okunması kolay değildir.
andrhamm

1

Bu çalışmalı:

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

1

Bu hack'i deneyebilirsiniz:

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

1

Yıkıcı değil ama yardımcı olabilir. JavaScript dokümantasyonuna ve ters yönteme göre şunu deneyebilirsiniz:

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

0

Kesinlikle, soru JavaScript Dizileri için Destructuring ile ilgili ve yıkıcı atamasını kullanarak bir Dizinin son öğesine sahip olmanın mümkün olmadığını biliyoruz, bunu değiştirilemez yapmanın bir yolu var, aşağıdakilere bakın:

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

arrDeğişkeni değiştirmiyoruz, ancak yine de son öğe hariç tüm dizi üyelerine bir dizi olarak ve son öğeye ayrı ayrı sahibiz.


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.