Ottieni l'ultimo elemento in un array


1142

Ecco il mio codice JavaScript finora:

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

Attualmente richiede il penultimo elemento dell'array dall'URL. Tuttavia, voglio fare un controllo per l'ultimo elemento dell'array "index.html"e, in tal caso, afferrare invece il terzo all'ultimo elemento.

Risposte:


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

Nel caso in cui il server serve la stessa lima per "index.html" e "index.html" è anche possibile utilizzare: .toLowerCase().

Tuttavia, potresti prendere in considerazione l'idea di fare questo lato server, se possibile: sarà più pulito e funzionerà per le persone senza JS.


se hai solo bisogno dell'ultimo articolo puoi Array.pop ()
Badri Derakhshan

1052

Non sono sicuro che ci sia un inconveniente, ma questo sembra abbastanza conciso:

arr.slice(-1)[0] 

o

arr.slice(-1).pop()

Entrambi restituiranno undefinedse l'array è vuoto.


32
anche usare la destrutturazione è bello:const [lastItem] = arr.slice(-1)
diachedelico l'

@diachedelic questo è il modo più elegante! Eccezionale!
Trufa,

2
.pop()rimuove l'ultimo elemento che modifica l'array originale. Non è lo stesso del semplice recupero di quel valore.
Badrush,

4
@Badrush slice () crea un nuovo array con una copia di un singolo elemento e pop modifica solo quella copia. l'array originale rimane illeso
kritzikratzi

Ma dovresti evitare di creare nuove matrici a meno che questo codice non venga chiamato spesso. Altrimenti metterà a dura prova la raccolta dei rifiuti e / o farà utilizzare più memoria al browser.
mvmn

259

Usa Array.pop :

var lastItem = anArray.pop();

Importante : questo restituisce l'ultimo elemento e lo rimuove dall'array


165

Una versione più breve di ciò che ha pubblicato @chaiguy:

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

La lettura dell'indice -1 ritorna undefinedgià.

MODIFICARE:

In questi giorni la preferenza sembra usare i moduli ed evitare di toccare il prototipo o utilizzare uno spazio dei nomi globale.

export function last(array) {
    return array[array.length - 1];
}

8
Se non è ovvio come questo è da effettivamente utilizzato, ecco un esempio: var lastItem = [3,2,1,5].last();. Il valore di lastItemè 5.
user128216

7
Questa risposta è corretta e anche abbastanza pulita MA (!!!) Una regola empirica che usa Javascript è quella Do NOT modify objects you Do NOT own. È pericoloso a causa di molte ragioni, come ad esempio 1. Altri sviluppatori che lavorano nel tuo team potrebbero confondersi in quanto questo metodo non è standard 2. con qualsiasi aggiornamento nelle librerie o anche utilizzando una versione ECMAScript inferiore o superiore potrebbe facilmente perdere PERSO!
Farzad YZ,

1
Per chiunque si chieda, questo rompe Array.forEach (). Sono ancora d'accordo sul fatto che la modifica dei prototipi non è la cosa peggiore in circolazione, ma questa è negativa.
Seph Reed,

1
Imo non c'è un grosso problema con la modifica Array.prototype, ma dovresti usare Object.assign(Array.prototype, 'last', { value: function () { … } });. Altrimenti la proprietà sarà enumerabile.
黄 雨伞


70

Ecco come ottenerlo senza alcun effetto sull'ARRAY originale

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

Se usi pop (), modificherà l'array

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

Ma puoi usarlo in modo che non abbia alcun effetto sull'array originale:

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 

6
dovresti fare slice (-1) .pop (), altrimenti copi l'intero array (devi solo copiare l'ultimo elemento).
kritzikratzi,

Non è necessario pop()quindi: bastaarr.slice(-1)[0]
Christophe Marois,

56

Il modo più pulito di ES6 (IMO) sarebbe:

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

Questo evita la mutazione foo, come .pop()avremmo fatto, se non avessimo utilizzato l'operatore di diffusione.
Detto questo, mi piace anche la foo.slice(-1)[0]soluzione.


1
È inoltre possibile utilizzare l'array destructuring per renderlo più ES6;) stackoverflow.com/a/46485581/31671
alex

36
Si noti che questa soluzione esegue una copia dell'intero array.
Brendan Annable,

4
È tanto illeggibile quanto .slice(-1)[0]ma è più lento. Potrebbe anche usare.slice
fregante

12
Copiare l'intero array solo per una sintassi "pulita" mi sembra sciocco. Non sembra nemmeno così carino
Jemar Jones,

43

Preferirei usare gli array.pop()indici.

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

in questo modo ottieni sempre l'elemento precedente a index.html (a condizione che l'array abbia isolato index.html come un unico elemento). Nota: tuttavia , perderai gli ultimi elementi dell'array.


38

Penso che se vuoi solo ottenere l'elemento senza rimuoverlo, è più semplice usare questo:

arr.slice(-1)[0]

Nota: se l'array è vuoto (ad es. []) Questo ritornerà undefined.

a proposito ... non ho controllato le prestazioni, ma penso che sia più semplice e pulito da scrivere


Si noti che a) questo non restituisce l'ultimo valore ma un array con l'ultimo elemento ( arr.slice(-1)[0] === arr[arr.length - 1]) eb) è lento perché viene copiato arrin un nuovo array (vedere stackoverflow.com/a/51763533/2733244 per la misurazione delle prestazioni).
Wortwart,

33

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

Array.prototype.slice con -1 può essere utilizzato per creare un nuovo array contenente solo l'ultimo elemento dell'array originale, quindi è possibile utilizzare Destructuring Assignment per creare una variabile utilizzando il primo elemento di quel nuovo array.

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

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


30

È possibile ottenere l'ultimo elemento di un array utilizzando il metodo slice con valori negativi.

Puoi leggere di più a riguardo qui in fondo.

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

L'uso di pop () cambierà l'array, il che non è sempre una buona idea.


1
Slice restituisce un array, tuttavia, quindi usa arr.slice(-1)[0], come questa risposta .
Cees Timmerman,

4
Se le prestazioni sono un problema, sappi che questo metodo è molto più lento di array[array.length - 1] jsperf.com/get-last-item-from-array/13
Bruno Peres

29

Puoi usare questo modello ...

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

Mentre legge piuttosto bene, tieni presente che crea un nuovo array, quindi è meno efficiente di altre soluzioni, ma non sarà quasi mai il collo di bottiglia delle prestazioni della tua applicazione.


25

Questa domanda è in sospeso da molto tempo, quindi sono sorpreso che nessuno abbia menzionato il fatto di rimettere l'ultimo elemento dopo un pop().

arr.pop()è esattamente efficiente arr[arr.length-1]ed entrambi hanno la stessa velocità di arr.push().

Pertanto, puoi cavartela con:

--- MODIFICATO [verifica che thePopnon sia undefinedprima di premere] ---

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

--- MODIFICA FINE ---

Che può essere ridotto a questo (stessa velocità [EDIT: ma non sicuro!]):

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

Questo è due volte più lento di arr[arr.length-1], ma non è necessario spostarsi con un indice. Vale la pena l'oro in qualsiasi giorno.

Delle soluzioni che ho provato, e in multipli di Execution Time Unit (ETU) di arr[arr.length-1]:

[Metodo] .............. [ETUs 5 elems] ... [ETU 1 milione elems]

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

Le ultime tre opzioni, IN PARTICOLARE [...arr].pop(), peggiorano MOLTO molto di più all'aumentare della dimensione dell'array. Su una macchina senza i limiti di memoria della mia macchina, [...arr].pop()probabilmente mantiene qualcosa come il suo rapporto 120: 1. Tuttavia, a nessuno piace un porco di risorse.


3
Se l'array iniziale può essere vuoto, questo approccio risulterà errato e []verrà trasformato in [undefined]. Devi proteggere la spinta all'indietro con un undefinedcontrollo esplicito , qualcosa del generemyPop !== undefined && arr.push(myPop)
dhilt

23

Se uno vuole ottenere l'ultimo elemento in una volta sola, può usare Array#splice():

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

Qui, non è necessario archiviare gli elementi divisi in un array, quindi arrivare all'ultimo elemento. Se ottenere l'ultimo elemento è l'unico obiettivo, questo dovrebbe essere usato.

Nota: questo modifica l'array originale rimuovendo il suo ultimo elemento. Pensa splice(-1,1)a una pop()funzione che apre l'ultimo elemento.


5
Questo non restituisce l'ultimo elemento in un array, anziché l'ultimo elemento stesso?

2
@tozazaburo non è la stessa cosa?
Aram Kocharyan,

5
questo modifica l'array. potresti usare slice (-1) invece di splice (-1) per lasciare intatta la matrice originale. @AramKocharyan su no la sua non, confrontare ["hi"]vs "hi".
kritzikratzi,

20

Per coloro che non hanno paura di sovraccaricare il prototipo di array (e con il mascheramento di enumerazione non dovresti essere):

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


18

In genere uso underscorejs , con cui puoi semplicemente farlo

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

Per me è più semantico di loc_array.slice(-1)[0]


18

Ecco più arte Javascript se sei venuto qui a cercarla

Nello spirito di un'altra risposta che ha usato reduceRight(), ma più breve:

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

Si basa sul fatto che, nel caso in cui non si fornisca un valore iniziale, l'ultimo elemento viene selezionato come quello iniziale (controllare i documenti qui ). Poiché il callback continua a restituire il valore iniziale, l'ultimo elemento sarà quello restituito alla fine.

Attenzione che questo dovrebbe essere considerato arte Javascript e non è affatto il modo in cui lo consiglierei, soprattutto perché funziona in tempo O (n), ma anche perché danneggia la leggibilità.

E ora per la risposta seria

Il modo migliore che vedo (considerando che lo vuoi più conciso di array[array.length - 1]) è questo:

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

Quindi basta usare la funzione:

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

La funzione è effettivamente utile nel caso in cui tu abbia a che fare con un array anonimo come [3, 2, 1, 5]usato sopra, altrimenti dovresti istanziarlo due volte, il che sarebbe inefficiente e brutto:

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

Ugh.

Ad esempio, ecco una situazione in cui hai un array anonimo e dovresti definire una variabile, ma puoi usare last()invece:

last("1.2.3".split("."));

16

Metto solo un'altra opzione qui.

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

Ho trovato l'approccio sopra più pulito e breve onliner. Per favore, sentiti libero di provare questo.

Nota: modificherà l'array originale, se non si desidera modificarlo, è possibile utilizzarlo slice()

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

Grazie @VinayPai per averlo segnalato.



13

Diversi modi per trovare l'ultimo valore di un array in javascript

  • Senza influire sull'array originale

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

  • Modifica l'array originale

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

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

  • Creando il proprio metodo di supporto

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

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

console.log(arr.last);


Se il tuo primo esempio in cui dichiari "Senza influire sull'array originale" e facendo come suggerito: console.log(arr.reverse()[0]) - congratulazioni, hai appena modificato l'array originale.
Roko C. Buljan,

12
const lastElement = myArray[myArray.length - 1];

Questa è la migliore opzione dal punto di vista delle prestazioni (~ 1000 volte più veloce di arr.slice (-1)).


10

Personalmente vorrei dare una risposta a kuporific / kritzikratzi. Il metodo array [array.length-1] diventa molto brutto se si lavora con array nidificati.

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]


10

Per impedire la rimozione dell'ultimo elemento dall'array di origine che è possibile utilizzare

Array.from(myArray).pop()

Principalmente supportato da tutti i browser (ES6)


1
buona fortuna con grandi array di almeno 100.000 elementi.
Soldeplata Saketos,

9

È possibile aggiungere una last()funzione al Arrayprototipo.

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

9

Qualunque cosa tu faccia, non usare soloreverse() !!!

Alcune risposte menzionano reversema non menzionano il fatto che reversemodifica l'array originale e che non restituisce una copia (come in altri linguaggi o framework).

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

animals.reverse()[0]
"cat"

animals.reverse()[0]
"dog"

animals.reverse()[1]
"dog"

animals.reverse()[1]
"cat"

Questo può essere il peggior tipo di codice per il debug!


4
Se si desidera una copia invertita dell'array, è possibile utilizzare subito l'operatore di diffusione. ad es.[...animals].reverse()
Josh R

puoi semplicemente copiare l'array prima di usare reverse[1,3,4,5,"last"].slice().reverse()[0]
Madeo

9

La distruzione degli oggetti ES6 è un'altra strada da percorrere.

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

È possibile estrarre la proprietà della lunghezza dall'array utilizzando la distruzione degli oggetti. Si crea un'altra chiave dinamica utilizzando la chiave già estratta di [lunghezza-1] e la si assegna per durare , tutto in una riga.


un po 'complicato ma intelligente.
Adrien Castagliola,

Grazie, puoi spiegare cosa fa esattamente?
Tarun Nagpal,

8

È possibile aggiungere un nuovo getter di proprietà al prototipo di inArray modo che sia accessibile attraverso tutte le istanze di Array.

I Getter ti consentono di accedere al valore di ritorno di una funzione proprio come se fosse il valore di una proprietà. Il valore di ritorno della funzione ovviamente è l'ultimo valore dell'array ( this[this.length - 1]).

Infine lo avvolgi in una condizione che controlla se la lastproprietà è ancora undefined(non definita da un altro script che potrebbe fare affidamento su di essa).

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'

Non funziona in IE ≤ 8.


Array.prototype.lastè sempre undefined? L'if non funziona con Chrome 36
bryc il

7

MODIFICATO:

Di recente ho trovato un'altra soluzione che ora ritengo sia la migliore per le mie esigenze:

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

Con la definizione sopra in vigore ora posso dire:

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

Il nome "w" sta per "wrapper". Puoi vedere come aggiungere facilmente altri metodi oltre a "last ()" in questo wrapper.

Dico "il meglio per le mie esigenze", perché ciò mi consente di aggiungere facilmente altri "metodi di supporto" a qualsiasi tipo di JavaScript incorporato. Ciò che viene in mente sono ad esempio car () e cdr () di Lisp.


Perché usare un wrapper? Se devi chiamare una wfunzione, fai semplicemente in modo che la funzione restituisca l'ultimo elemento.
fregante,

w([1,2,3]).lengthnon è definito. w([1,2,3])[1]non è definito. A me non sembra un involucro. E c'è un errore di sintassi. Hai un extra ';'. Vedere stackoverflow.com/a/49725374/458321 per come scrivere un wrapper di classe (classe SutString) e utilizzare la riflessione per popolare quel wrapper. Tuttavia, imho, i wrapper sono eccessivi. Meglio usare l'incapsulamento, come quasi hai. return { arr: anArray, last() { return anArray[anArray.length - 1]; } };. Inoltre, w è troppo generico. La chiamata è ArrayW o qualcosa del genere.
TamusJRoyce,

6

Penso che il modo più semplice e super inefficiente sia:

var array = ['fenerbahce','arsenal','milan'];
var reversed_array = array.reverse(); //inverts array [milan,arsenal,fenerbahce]
console.log(reversed_array[0]) // result is "milan".

43
Questa soluzione richiede O (n) più memoria e richiede O (n) tempo. Non è davvero la soluzione ideale.
hlin117,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.