Dapatkan item terakhir dalam sebuah array

1142

Ini kode JavaScript saya sejauh ini:

var linkElement = document.getElementById("BackButton");
var loc_array = document.location.href.split('/');
var newT = document.createTextNode(unescape(capWords(loc_array[loc_array.length-2]))); 
linkElement.appendChild(newT);

Saat ini dibutuhkan item kedua hingga terakhir dalam array dari URL. Namun, saya ingin melakukan pengecekan untuk item terakhir dalam array menjadi "index.html"dan jika demikian, ambil item ketiga menjadi terakhir.

Balexander
sumber

Jawaban:

1225
if (loc_array[loc_array.length - 1] === 'index.html') {
   // do something
} else {
   // something else
}

Dalam hal server Anda berfungsi file yang sama untuk "index.html" dan "index.html" Anda juga dapat menggunakan: .toLowerCase().

Meskipun, Anda mungkin ingin mempertimbangkan melakukan sisi server ini jika mungkin: itu akan lebih bersih dan berfungsi untuk orang tanpa JS.

Aaron Harun
sumber
1052

Tidak yakin apakah ada kekurangan, tetapi ini tampaknya cukup singkat:

arr.slice(-1)[0] 

atau

arr.slice(-1).pop()

Keduanya akan kembali undefinedjika array kosong.

kritzikratzi
sumber
32
menggunakan const [lastItem] = arr.slice(-1)
destrrukturisasi
@diachedelic, ini adalah cara paling keren! Luar biasa!
Trufa
2
.pop()menghapus elemen terakhir yang memodifikasi array asli. Ini tidak sama dengan hanya mengambil nilai itu.
Badrush
4
@Badrush slice () membuat array baru dengan salinan elemen tunggal, dan pop hanya memodifikasi salinan itu. array asli tetap tidak terluka
kritzikratzi
Tetapi Anda harus menghindari membuat array baru kecuali kode ini tidak sering dipanggil. Jika tidak, ini akan menambah beban pada pengumpulan sampah, dan / atau akan membuat browser menggunakan lebih banyak memori.
mvmn
259

Gunakan Array.pop :

var lastItem = anArray.pop();

Penting : Ini mengembalikan elemen terakhir dan menghapusnya dari array

mohawke
sumber
165

Versi pendek dari apa yang diposkan @chaiguy:

Array.prototype.last = function() {
    return this[this.length - 1];
}

Membaca indeks -1 undefinedsudah kembali .

EDIT:

Hari-hari ini preferensi tampaknya menggunakan modul dan untuk menghindari menyentuh prototipe atau menggunakan namespace global.

export function last(array) {
    return array[array.length - 1];
}
Aram Kocharyan
sumber
8
Jika tidak jelas bagaimana ini harus benar-benar digunakan, inilah contoh: var lastItem = [3,2,1,5].last();. Nilai lastItemadalah 5.
user128216
7
Jawaban ini benar dan juga cukup TETAPI (!!!) Aturan praktis menggunakan Javascript adalah itu Do NOT modify objects you Do NOT own. Ini berbahaya karena banyak alasan, seperti 1. Pengembang lain yang bekerja di tim Anda dapat menjadi bingung karena metode ini tidak standar 2.dengan pembaruan apa pun di perpustakaan atau bahkan menggunakan versi ECMAScript yang lebih rendah atau lebih tinggi, ia dapat dengan mudah HILANG!
Farzad YZ
1
Bagi siapa pun yang bertanya-tanya, ini memecah Array.forEach (). Saya masih setuju bahwa memodifikasi prototipe bukan yang terburuk di luar sana, tetapi yang ini buruk.
Seph Reed
1
Imo tidak ada masalah besar dengan modifikasi Array.prototype, tetapi Anda harus menggunakannya Object.assign(Array.prototype, 'last', { value: function () { … } });. Kalau tidak, properti akan dihitung.
黄 雨伞
70

Begini cara mendapatkannya tanpa efek pada ARRAY asli

a = [1,2,5,6,1,874,98,"abc"];
a.length; //returns 8 elements

Jika Anda menggunakan pop (), itu akan mengubah array Anda

a.pop();  // will return "abc" AND REMOVES IT from the array 
a.length; // returns 7

Tetapi Anda dapat menggunakan ini sehingga tidak berpengaruh pada array asli:

a.slice(-1).pop(); // will return "abc" won't do modify the array 
                   // because slice creates a new array object 
a.length;          // returns 8; no modification and you've got you last element 
ucefkh
sumber
6
Anda harus melakukan slice (-1) .pop (), jika tidak, Anda menyalin seluruh array (Anda benar-benar hanya perlu menyalin elemen terakhir).
kritzikratzi
pop()Maka tidak perlu untuk itu : lakukan sajaarr.slice(-1)[0]
Christophe Marois
56

Cara ES6 "terbersih" (IMO) adalah:

const foo = [1,2,3,4];
const bar = [...foo].pop();

Ini menghindari bermutasi foo, seperti .pop()seharusnya, jika kami tidak menggunakan operator spread.
Yang mengatakan, saya suka juga foo.slice(-1)[0]solusinya.

ddd
sumber
1
Anda juga dapat menggunakan array restrukturisasi untuk membuatnya lebih ES6;) stackoverflow.com/a/46485581/31671
alex
36
Perhatikan bahwa solusi ini melakukan salinan seluruh array.
Brendan Annable
4
Sama tidak terbaca .slice(-1)[0]tetapi lebih lambat. Bisa juga digunakan.slice
gratis
12
Menyalin seluruh array hanya untuk sintaks "bersih" tampaknya konyol bagi saya. Bahkan tidak kelihatan bagus
Jemar Jones
43

Saya lebih suka menggunakan array.pop()daripada indeks.

while(loc_array.pop()!= "index.html"){
}
var newT = document.createTextNode(unescape(capWords(loc_array[loc_array.length])));

dengan cara ini Anda selalu mendapatkan elemen sebelum index.html (menyediakan array Anda telah mengisolasi index.html sebagai satu item). Catatan: Anda akan kehilangan elemen terakhir dari array.

Pablo Mescher
sumber
38

Saya pikir jika Anda hanya ingin mendapatkan elemen tanpa menghapus, lebih mudah gunakan ini:

arr.slice(-1)[0]

Catatan: Jika array kosong (mis. []) Ini akan kembali undefined.

omong-omong ... saya tidak memeriksa kinerja, tetapi saya pikir lebih sederhana dan bersih untuk menulis

Web yang mengerikan
sumber
Perhatikan bahwa a) ini tidak mengembalikan nilai terakhir tetapi array dengan elemen terakhir ( arr.slice(-1)[0] === arr[arr.length - 1]), dan b) lambat karena ia menyalin arrke array baru (lihat stackoverflow.com/a/51763533/2733244 untuk pengukuran kinerja).
cepat
33

const [lastItem] = array.slice(-1);

Array.prototype.slice dengan -1 dapat digunakan untuk membuat Array baru yang hanya berisi item terakhir dari Array asli, Anda kemudian dapat menggunakan Destrukturisasi Assignment untuk membuat variabel menggunakan item pertama dari Array baru.

const lotteryNumbers = [12, 16, 4, 33, 41, 22];
const [lastNumber] = lotteryNumbers.slice(-1);

console.log(lotteryNumbers.slice(-1));
// => [22]
console.log(lastNumber);
// => 22

Jamie Mason
sumber
30

Mendapatkan item terakhir dari sebuah array dapat dicapai dengan menggunakan metode slice dengan nilai negatif.

Anda dapat membaca lebih lanjut di sini di bagian bawah.

var fileName = loc_array.slice(-1)[0];
if(fileName.toLowerCase() == "index.html")
{
  //your code...
}

Menggunakan pop () akan mengubah array Anda, yang tidak selalu merupakan ide yang bagus.

Mohoch
sumber
1
Slice mengembalikan array, jadi gunakan arr.slice(-1)[0], seperti jawaban ini .
Cees Timmerman
4
Jika kinerja merupakan masalah, ketahuilah bahwa metode ini jauh lebih lambat daripada array[array.length - 1] jsperf.com/get-last-item-from-array/13
Bruno Peres
29

Anda dapat menggunakan pola ini ...

let [last] = arr.slice(-1);

Sementara itu berbunyi agak baik, perlu diingat itu menciptakan sebuah array baru sehingga kurang efisien dibandingkan solusi lain tetapi hampir tidak pernah akan dengan hambatan kinerja aplikasi Anda.

alex
sumber
25

Pertanyaan ini sudah ada sejak lama, jadi saya terkejut bahwa tidak ada yang menyebutkan hanya mengembalikan elemen terakhir setelah pop().

arr.pop()persis seefisien arr[arr.length-1], dan keduanya sama kecepatannya arr.push().

Karena itu, Anda bisa lolos dengan:

--- DIedit [periksa itu thePopbukan undefinedsebelum mendorong] ---

let thePop = arr.pop()
thePop && arr.push(thePop)

--- AKHIR EDIT ---

Yang bisa direduksi menjadi ini (kecepatan yang sama [EDIT: tapi tidak aman!]):

arr.push(thePop = arr.pop())    //Unsafe if arr empty

Ini dua kali lebih lambat arr[arr.length-1], tetapi Anda tidak perlu mencari-cari indeks. Itu bernilai emas setiap hari.

Dari solusi yang saya coba, dan dalam kelipatan Unit Waktu Eksekusi (ETU) dari arr[arr.length-1]:

[Metode] .............. [ETU 5 elem] ... [ETU 1 juta elem]

arr[arr.length - 1]      ------> 1              -----> 1

let myPop = arr.pop()
arr.push(myPop)          ------> 2              -----> 2

arr.slice(-1).pop()      ------> 36             -----> 924  

arr.slice(-1)[0]         ------> 36             -----> 924  

[...arr].pop()           ------> 120            -----> ~21,000,000 :)

Tiga opsi terakhir, TERUTAMA [...arr].pop(), menjadi SANGAT jauh lebih buruk karena ukuran array meningkat. Pada mesin tanpa batasan memori mesin saya, [...arr].pop()mungkin mempertahankan sesuatu seperti rasio 120: 1. Namun, tidak ada yang suka babi sumber daya.

Paul Parker
sumber
3
Jika array awal dapat kosong, pendekatan ini akan menghasilkan salah dan []akan diubah menjadi [undefined]. Anda perlu melindungi backward push dengan undefinedcek eksplisit , sesuatu sepertimyPop !== undefined && arr.push(myPop)
dhilt
23

Jika seseorang ingin mendapatkan elemen terakhir sekaligus, ia dapat menggunakan Array#splice():

lastElement = document.location.href.split('/').splice(-1,1);

Di sini, tidak perlu menyimpan elemen yang terpecah dalam array, dan kemudian sampai ke elemen terakhir. Jika mendapatkan elemen terakhir adalah satu-satunya tujuan, ini harus digunakan.

Catatan: Ini mengubah array asli dengan menghapus elemen terakhirnya. Anggap splice(-1,1)sebagai pop()fungsi yang muncul elemen terakhir.

pengguna1144616
sumber
5
Bukankah ini mengembalikan elemen terakhir dalam array, bukan elemen terakhir itu sendiri?
2
@ tozazaburo bukankah itu hal yang sama?
Aram Kocharyan
5
ini memodifikasi array. Anda bisa menggunakan slice (-1) alih-alih splice (-1) untuk membiarkan array asli tidak tersentuh. @AramKocharyan Tidak ada yang tidak, membandingkan ["hi"]vs "hi".
kritzikratzi
20

Bagi mereka yang tidak takut untuk membebani prototipe Array (dan dengan cara penghitungan, Anda seharusnya tidak):

Object.defineProperty( Array.prototype, "getLast", {
    enumerable: false,
    configurable: false,
    writable: false,
    value: function() {
        return this[ this.length - 1 ];
    }
} );
devios1
sumber
18

jQuery memecahkan ini dengan rapi:

> $([1,2,3]).get(-1)
3
> $([]).get(-1)
undefined
Cees Timmerman
sumber
18

Saya biasanya menggunakan underscorejs , dengan itu Anda bisa melakukannya

if (_.last(loc_array) === 'index.html'){
  etc...
}

Bagi saya itu lebih semantik daripada loc_array.slice(-1)[0]

niels
sumber
18

Ini lebih banyak seni Javascript jika Anda datang ke sini mencarinya

Dengan semangat jawaban lain yang digunakan reduceRight(), tetapi lebih pendek:

[3, 2, 1, 5].reduceRight(a => a);

Itu bergantung pada fakta bahwa, jika Anda tidak memberikan nilai awal, elemen terakhir dipilih sebagai yang awal (periksa dokumen di sini ). Karena panggilan balik hanya mengembalikan nilai awal, elemen terakhir akan menjadi yang dikembalikan pada akhirnya.

Berhati-hatilah karena ini harus dianggap sebagai seni Javascript dan sama sekali tidak seperti cara saya akan merekomendasikan melakukannya, terutama karena itu berjalan dalam waktu O (n), tetapi juga karena itu menyakitkan keterbacaan.

Dan sekarang untuk jawaban yang serius

Cara terbaik yang saya lihat (mengingat Anda menginginkannya lebih ringkas daripada array[array.length - 1]) adalah ini:

const last = a => a[a.length - 1];

Kemudian gunakan saja fungsinya:

last([3, 2, 1, 5])

Fungsi ini sebenarnya berguna jika Anda berurusan dengan array anonim seperti yang [3, 2, 1, 5]digunakan di atas, jika tidak Anda harus instantiate dua kali, yang akan menjadi tidak efisien dan jelek:

[3, 2, 1, 5][[3, 2, 1, 5].length - 1]

Ugh.

Misalnya, inilah situasi di mana Anda memiliki array anonim dan Anda harus mendefinisikan variabel, tetapi Anda bisa menggunakannya last()sebagai gantinya:

last("1.2.3".split("."));
Lucio Paiva
sumber
16

Hanya menempatkan opsi lain di sini.

loc_array.splice(-1)[0] === 'index.html'

Saya menemukan pendekatan di atas lebih bersih dan onliner pendek. Tolong, jangan ragu untuk mencoba yang ini.

Catatan: Ini akan mengubah array asli, jika Anda tidak ingin memodifikasinya, Anda dapat menggunakannya slice()

loc_array.slice(-1)[0] === 'index.html'

Terima kasih @VinayPai untuk menunjukkan ini.

sidgujrathi
sumber
13

Berbagai cara untuk menemukan nilai terakhir array dalam javascript

  • Tanpa memengaruhi array asli

var arr = [1,2,3,4,5];

console.log(arr.slice(-1)[0])
console.log(arr[arr.length-1])
const [last] = [...arr].reverse();
console.log(last)
console.log(arr.reverse()[0])

  • Memodifikasi array asli

var arr = [1,2,3,4,5];

console.log(arr.pop())
arr.push(5)
console.log(...arr.splice(-1));

  • Dengan membuat metode pembantu sendiri

let arr = [1, 2, 3, 4, 5];

Object.defineProperty(arr, 'last', 
{ get: function(){
  return this[this.length-1];
 }
})

console.log(arr.last);

Vahid Akhtar
sumber
Jika contoh pertama Anda di mana Anda menyatakan "Tanpa memengaruhi array asli" dan dengan melakukan seperti yang disarankan: console.log(arr.reverse()[0]) - selamat, Anda baru saja memodifikasi array asli.
Roko C. Buljan
12
const lastElement = myArray[myArray.length - 1];

Ini adalah opsi terbaik dari sudut pandang kinerja (~ 1000 kali lebih cepat daripada arr.slice (-1)).

Alexander Burakevych
sumber
10

Secara pribadi saya akan menjawab dengan jawaban kuporific / kritzikratzi. Metode array [array.length-1] menjadi sangat jelek jika Anda bekerja dengan array bersarang.

var array = [[1,2,3], [4,5,6], [7,8,9]]

array.slice(-1)[0]

//instead of 

array[array.length-1]

//Much easier to read with nested arrays

array.slice(-1)[0].slice(-1)[0]

//instead of

array[array.length-1][array[array.length-1].length-1]
Michael Falck Wedelgård
sumber
10

Untuk mencegah penghapusan item terakhir dari array asal, Anda dapat menggunakan

Array.from(myArray).pop()

Yang paling didukung dari semua browser (ES6)

Alexandr Malinin
sumber
1
semoga sukses dengan array besar 100.000 elemen atau lebih.
Soldeplata Saketos
9

Anda dapat menambahkan last()fungsi ke Arrayprototipe.

Array.prototype.last = function () {
    return this[this.length - 1];
};
trinalbadger587
sumber
9

Apa pun yang Anda lakukan jangan hanya gunakan reverse()!!!

Beberapa jawaban menyebutkan reversetetapi tidak menyebutkan fakta bahwa reversememodifikasi array asli, dan tidak (seperti dalam beberapa bahasa atau kerangka kerja lain) mengembalikan salinan.

var animals = ['dog', 'cat'];

animals.reverse()[0]
"cat"

animals.reverse()[0]
"dog"

animals.reverse()[1]
"dog"

animals.reverse()[1]
"cat"

Ini bisa menjadi jenis kode terburuk untuk di-debug!

Simon_Weaver
sumber
4
Jika Anda menginginkan salinan array Anda yang dibalik , Anda dapat menggunakan operator spread sekarang. misalnya[...animals].reverse()
Josh R
Anda cukup menyalin array sebelum menggunakan reverse[1,3,4,5,"last"].slice().reverse()[0]
Madeo
9

Penghancuran objek ES6 adalah cara lain untuk pergi.

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

Anda mengekstrak properti panjang dari Array menggunakan perusakan objek. Anda membuat kunci dinamis lain menggunakan kunci yang sudah diekstraksi oleh [length-1] dan menetapkannya untuk bertahan lama , semuanya dalam satu baris.

gautamits
sumber
sedikit rumit tapi pintar.
Adrien Castagliola
Terima kasih, bisakah Anda menjelaskan apa sebenarnya yang dilakukannya?
Tarun Nagpal
8

Anda bisa menambahkan pengambil properti baru ke prototipeArray sehingga dapat diakses melalui semua contoh Array.

Getters memungkinkan Anda untuk mengakses nilai pengembalian suatu fungsi sama seperti nilai properti. Nilai kembali dari fungsi tentu saja adalah nilai terakhir dari array ( this[this.length - 1]).

Akhirnya Anda membungkusnya dalam kondisi yang memeriksa apakah last-property masih undefined(tidak ditentukan oleh skrip lain yang mungkin bergantung padanya).

if(typeof Array.prototype.last === 'undefined') {
    Object.defineProperty(Array.prototype, 'last', {
        get : function() {
            return this[this.length - 1];
        }
    });
}

// Now you can access it like
[1, 2, 3].last;            // => 3
// or
var test = [50, 1000];
alert(test.last);          // Says '1000'

Tidak bekerja di IE ≤ 8.

Matmarbon
sumber
Array.prototype.lastselalu undefined? Jika tidak bekerja di bawah Chrome 36
bryc
7

Diedit:

Baru-baru ini saya menemukan satu solusi lagi yang sekarang saya pikir merupakan yang terbaik untuk kebutuhan saya:

function w(anArray) {
  return {
    last() {
      return anArray [anArray.length - 1];
    };
  };
}

Dengan definisi di atas yang berlaku sekarang saya dapat mengatakan:

let last = w ([1,2,3]).last();
console.log(last) ; // -> 3

Nama "w" adalah singkatan dari "wrapper". Anda dapat melihat bagaimana Anda dapat dengan mudah menambahkan lebih banyak metode selain 'last ()' ke pembungkus ini.

Saya mengatakan "terbaik untuk kebutuhan saya", karena ini memungkinkan saya untuk dengan mudah menambahkan "metode pembantu" lainnya ke semua tipe bawaan JavaScript. Apa yang terlintas dalam pikiran adalah mobil () dan cdr () dari Lisp misalnya.

Panu Logic
sumber
Mengapa menggunakan pembungkus? Jika Anda harus memanggil wfungsi, buat saja fungsi mengembalikan item terakhir.
fregante
w([1,2,3]).lengthtidak terdefinisi. w([1,2,3])[1]tidak terdefinisi. Tidak tampak seperti pembungkus bagi saya. Dan ada kesalahan sintaksis. Anda memiliki tambahan ';'. Lihat stackoverflow.com/a/49725374/458321 untuk cara menulis pembungkus kelas (kelas SutString) dan menggunakan refleksi untuk mengisi pembungkus itu. Padahal, imho, pembungkusnya terlalu banyak. Lebih baik menggunakan enkapsulasi, seperti yang hampir Anda miliki. return { arr: anArray, last() { return anArray[anArray.length - 1]; } };. Juga, w terlalu generik. Panggilan adalah ArrayW atau sesuatu.
TamusJRoyce
6

Saya pikir cara termudah dan super tidak efisien adalah:

var array = ['fenerbahce','arsenal','milan'];
var reversed_array = array.reverse(); //inverts array [milan,arsenal,fenerbahce]
console.log(reversed_array[0]) // result is "milan".
Osman Erdi
sumber
43
Solusi ini membutuhkan O (n) lebih banyak memori dan membutuhkan waktu O (n). Ini benar-benar bukan solusi ideal.
hlin117