Qual è il modo migliore per ottenere l'ultimo elemento di un array senza eliminarlo?


427

Ok,

So tutto array_pop(), ma questo cancella l'ultimo elemento. Qual è il modo migliore per ottenere l'ultimo elemento di un array senza eliminarlo?

EDIT: ecco un bonus:

$array = array('a' => 'a', 'b' => 'b', 'c' => 'c');

o anche

$array = array('a', 'b', 'c', 'd');
unset($array[2]);
echo $array[sizeof($array) - 1]; // Output: PHP Notice:  Undefined offset:  2 in - on line 4

11
Che ci crediate o non lo faccia scoppiare e rimetterlo su è uno dei modi più veloci con cui ho fatto un benchmark. $ val = $ array [] = array_pop ($ array); echo $ val;
user2782001,

2
Questa domanda ha prodotto molte opzioni. Per aiutarmi a scegliere, ho fatto un confronto tra le opzioni più importanti / distinte e ho condiviso i risultati come una risposta separata . (: @ user2782001 ha suggerito il mio preferito finora nel commento sopra. :) Grazie a tutti per il contributo!
Paul van Leeuwen,

1
@TheodoreRSmith Quando PHP 7.3 viene rilasciato si potrebbe considerare la possibilità ( questo suggerimento per il clone di Quasimodo la 'risposta accettato' (per la vostra considerazione) ...
Paul van Leeuwen

Risposte:


176

Le molte risposte in questo thread ci presentano molte diverse opzioni. Per poter scegliere tra loro avevo bisogno di capire il loro comportamento e le loro prestazioni. In questa risposta voglio condividere i miei risultati con voi, confrontata con le versioni di PHP 5.6.38, 7.2.10e 7.3.0RC1( atteso 13 dicembre 2018 ).

Le opzioni <<option code>>che testerò sono:

(funzioni menzionate: array_key_last , array_keys , array_pop , array_slice , array_values , count , end , reset )

Gli ingressi di test <<input code>>da combinare con:

  • null =$array = null;
  • vuoto =$array = [];
  • last_null =$array = ["a","b","c",null];
  • auto_idx =$array = ["a","b","c","d"];
  • shuffle =$array = []; $array[1] = "a"; $array[2] = "b"; $array[0] = "c";
  • 100 =$array = []; for($i=0;$i<100;$i++) { $array[] = $i; }
  • 100000 =$array = []; for($i=0;$i<100000;$i++) { $array[] = $i; }

Per testare userò il 5.6.38, 7.2.10e 7.3.0RC1 contenitori docker PHP come:

sudo docker run -it --rm php:5.6.38-cli-stretch php -r '<<<CODE HERE>>>'

Ogni combinazione di quanto sopra elencato <<option code>>s e <<input code>>s verrà eseguito su tutte le versioni di PHP. Per ogni test eseguito viene utilizzato il seguente frammento di codice:

<<input code>>  error_reporting(E_ALL);  <<option code>>  error_reporting(0); $before=microtime(TRUE); for($i=0;$i<100;$i++){echo ".";for($j=0;$j<100;$j++){  <<option code>>  }}; $after=microtime(TRUE); echo "\n"; var_dump($x); echo round(($after-$before)/(100*100)*1000*1000*1000);

Per ogni esecuzione questo var_dump l'ultimo valore recuperato dell'ingresso di prova e stampa la durata media di un'iterazione in femtosecondi (0,000000000000001001 di secondo).

I risultati sono i seguenti:

/==========================================================================================================================================================================================================================================================================================================================================================================================================================\
||                                                                      ||                            T  E  S  T     I  N  P  U  T     -     5  .  6  .  3  8                            ||                             T  E  S  T     I  N  P  U  T     -     7  .  2  .  1  0                           ||                             T  E  S  T     I  N  P  U  T     -     7  .  3  .  0  R  C  1                     ||
||                                                                      ||          null |         empty |     last_null |      auto_idx |       shuffle |           100 |        100000 ||          null |         empty |     last_null |      auto_idx |       shuffle |           100 |        100000 ||          null |         empty |     last_null |      auto_idx |       shuffle |           100 |        100000 ||
||============================OPTIONS - ERRORS==========================++===============+===============+===============+===============+===============+===============+===============++===============+===============+===============+===============+===============+===============+===============++===============+===============+===============+===============+===============+===============+===============<|
||  1.  $x = array_values(array_slice($array, -1))[0];                  ||       W1 + W2 |            N1 |             - |             - |             - |             - |             - ||       W1 + W2 |            N1 |             - |             - |             - |             - |             - ||       W1 + W2 |            N1 |             - |             - |             - |             - |             - ||
||  2.  $x = array_slice($array, -1)[0];                                ||            W1 |            N1 |             - |             - |             - |             - |             - ||            W1 |            N1 |             - |             - |             - |             - |             - ||            W1 |            N1 |             - |             - |             - |             - |             - ||
||  3.  $x = array_pop((array_slice($array, -1)));                      ||       W1 + W3 |             - |             - |             - |             - |             - |             - ||  W1 + N2 + W3 |            N2 |            N2 |            N2 |            N2 |            N2 |            N2 ||  W1 + N2 + W3 |            N2 |            N2 |            N2 |            N2 |            N2 |            N2 ||
||  4.  $x = array_pop((array_slice($array, -1, 1)));                   ||       W1 + W3 |             - |             - |             - |             - |             - |             - ||  W1 + N2 + W3 |            N2 |            N2 |            N2 |            N2 |            N2 |            N2 ||  W1 + N2 + W3 |            N2 |            N2 |            N2 |            N2 |            N2 |            N2 ||
||  5.  $x = end($array); reset($array);                                ||       W4 + W5 |             - |             - |             - |             - |             - |             - ||       W4 + W5 |            N2 |            N2 |            N2 |            N2 |            N2 |            N2 ||       W4 + W5 |             - |             - |             - |             - |             - |             - ||
||  6.  $x = end((array_values($array)));                               ||       W2 + W4 |             - |             - |             - |             - |             - |             - ||  W2 + N2 + W4 |             - |             - |             - |             - |             - |             - ||  W2 + N2 + W4 |            N2 |            N2 |            N2 |            N2 |            N2 |            N2 ||
||  7.  $x = $array[count($array)-1];                                   ||             - |            N3 |             - |             - |             - |             - |             - ||            W7 |            N3 |             - |             - |             - |             - |             - ||            W7 |            N3 |             - |             - |             - |             - |             - ||
||  8.  $keys = array_keys($array); $x = $array[$keys[count($keys)-1]]; ||            W6 |       N3 + N4 |             - |             - |             - |             - |             - ||       W6 + W7 |       N3 + N4 |             - |             - |             - |             - |             - ||       W6 + W7 |       N3 + N4 |             - |             - |             - |             - |             - ||
||  9.  $x = $array[] = array_pop($array);                              ||            W3 |             - |             - |             - |             - |             - |             - ||            W3 |             - |             - |             - |             - |             - |             - ||            W3 |             - |             - |             - |             - |             - |             - ||
|| 10.  $x = $array[array_key_last($array)];                            ||            F1 |            F1 |            F1 |            F1 |            F1 |            F1 |            F1 ||            F2 |            F2 |            F2 |            F2 |            F2 |            F2 |            F2 ||            W8 |            N4 |            F2 |            F2 |            F2 |            F2 |            F2 ||
||========================OPTIONS - VALUE RETRIEVED=====================++===============+===============+===============+===============+===============+===============+===============++===============+===============+===============+===============+===============+===============+===============++===============+===============+===============+===============+===============+===============+===============<|
||  1.  $x = array_values(array_slice($array, -1))[0];                  ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||
||  2.  $x = array_slice($array, -1)[0];                                ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||
||  3.  $x = array_pop((array_slice($array, -1)));                      ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||
||  4.  $x = array_pop((array_slice($array, -1, 1)));                   ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||
||  5.  $x = end($array); reset($array);                                ||          NULL |   bool(false) |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||          NULL |   bool(false) |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||          NULL |   bool(false) |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||
||  6.  $x = end((array_values($array)));                               ||          NULL |   bool(false) |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||          NULL |   bool(false) |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||          NULL |   bool(false) |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||
||  7.  $x = $array[count($array)-1];                                   ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "b" |       int(99) |    int(99999) ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "b" |       int(99) |    int(99999) ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "b" |       int(99) |    int(99999) ||
||  8.  $keys = array_keys($array); $x = $array[$keys[count($keys)-1]]; ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||
||  9.  $x = $array[] = array_pop($array);                              ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||          NULL |          NULL |          NULL | string(1) "d" | string(1) "c" |       int(99) |    int(99999) ||
|| 10.  $x = $array[array_key_last($array)];                            ||           N/A |           N/A |           N/A |           N/A |           N/A |           N/A |           N/A ||           N/A |           N/A |           N/A |           N/A |           N/A |           N/A |           N/A ||           N/A |           N/A |           N/A |           N/A |           N/A |           N/A |           N/A ||
||=================OPTIONS - FEMTOSECONDS PER ITERATION=================++===============+===============+===============+===============+===============+===============+===============++===============+===============+===============+===============+===============+===============+===============++===============+===============+===============+===============+===============+===============+===============<|
||  1.  $x = array_values(array_slice($array, -1))[0];                  ||           803 |           466 |           390 |           384 |           373 |           764 |     1.046.642 ||           691 |           252 |           101 |           128 |            93 |           170 |        89.028 ||           695 |           235 |            90 |            97 |            95 |           188 |        87.991 ||
||  2.  $x = array_slice($array, -1)[0];                                ||           414 |           349 |           252 |           248 |           246 |           604 |     1.038.074 ||           373 |           249 |            85 |            91 |            90 |           164 |        90.750 ||           367 |           224 |            78 |            85 |            80 |           155 |        86.141 ||
||  3.  $x = array_pop((array_slice($array, -1)));                      ||           724 |           228 |           323 |           318 |           350 |           673 |     1.042.263 ||           988 |           285 |           309 |           317 |           331 |           401 |        88.363 ||           877 |           266 |           298 |           300 |           326 |           403 |        87.279 ||
||  4.  $x = array_pop((array_slice($array, -1, 1)));                   ||           734 |           266 |           358 |           356 |           349 |           699 |     1.050.101 ||           887 |           288 |           316 |           322 |           314 |           408 |        88.402 ||           935 |           268 |           335 |           315 |           313 |           403 |        86.445 ||
||  5.  $x = end($array); reset($array);                                ||           715 |           186 |           185 |           180 |           176 |           185 |           172 ||           674 |            73 |            69 |            70 |            66 |            65 |            70 ||           693 |            65 |            85 |            74 |            68 |            70 |            69 ||
||  6.  $x = end((array_values($array)));                               ||           877 |           205 |           320 |           337 |           304 |         2.901 |     7.921.860 ||           948 |           300 |           336 |           308 |           309 |           509 |    29.696.951 ||           946 |           262 |           301 |           309 |           302 |           499 |    29.234.928 ||
||  7.  $x = $array[count($array)-1];                                   ||           123 |           300 |           137 |           139 |           143 |           140 |           144 ||           312 |           218 |            48 |            53 |            45 |            47 |            51 ||           296 |           217 |            46 |            44 |            53 |            53 |            55 ||
||  8.  $keys = array_keys($array); $x = $array[$keys[count($keys)-1]]; ||           494 |           593 |           418 |           435 |           399 |         3.873 |    12.199.450 ||           665 |           407 |           103 |           109 |           114 |           431 |    30.053.730 ||           647 |           445 |            91 |            95 |            96 |           419 |    30.718.586 ||
||  9.  $x = $array[] = array_pop($array);                              ||           186 |           178 |           175 |           188 |           180 |           181 |           186 ||            83 |            78 |            75 |            71 |            74 |            69 |            83 ||            71 |            64 |            70 |            64 |            68 |            69 |            81 ||
|| 10.  $x = $array[array_key_last($array)];                            ||           N/A |           N/A |           N/A |           N/A |           N/A |           N/A |           N/A ||           N/A |           N/A |           N/A |           N/A |           N/A |           N/A |           N/A ||           370 |           223 |            49 |            52 |            61 |            57 |            52 ||
 \=========================================================================================================================================================================================================================================================================================================================================================================================================================/ 

I suddetti codici F atal, W arning e N otice si traducono in:

F1 = Fatal error: Call to undefined function array_key_last() in Command line code on line 1
F2 = Fatal error: Uncaught Error: Call to undefined function array_key_last() in Command line code:1
W1 = Warning: array_slice() expects parameter 1 to be array, null given in Command line code on line 1
W2 = Warning: array_values() expects parameter 1 to be array, null given in Command line code on line 1
W3 = Warning: array_pop() expects parameter 1 to be array, null given in Command line code on line 1
W4 = Warning: end() expects parameter 1 to be array, null given in Command line code on line 1
W5 = Warning: reset() expects parameter 1 to be array, null given in Command line code on line 1
W6 = Warning: array_keys() expects parameter 1 to be array, null given in Command line code on line 1
W7 = Warning: count(): Parameter must be an array or an object that implements Countable in Command line code on line 1
W8 = Warning: array_key_last() expects parameter 1 to be array, null given in Command line code on line 1
N1 = Notice: Undefined offset: 0 in Command line code on line 1
N2 = Notice: Only variables should be passed by reference in Command line code on line 1
N3 = Notice: Undefined offset: -1 in Command line code on line 1
N4 = Notice: Undefined index:  in Command line code on line 1

Sulla base di questo risultato, traggo le seguenti conclusioni:

  • le versioni più recenti di PHP funzionano meglio con l'eccezione di queste opzioni che sono diventate significativamente più lente:
    • opzione .6. $x = end((array_values($array)));
    • opzione .8. $keys = array_keys($array); $x = $array[$keys[count($keys)-1]];
  • queste opzioni sono ottimizzate per array molto grandi:
    • opzione .5. $x = end($array); reset($array);
    • opzione .7. $x = $array[count($array)-1];
    • opzione .9. $x = $array[] = array_pop($array);
    • opzione 10. $x = $array[array_key_last($array)]; (da PHP 7.3)
  • queste opzioni dovrebbero essere utilizzate solo per array auto-indicizzati :
    • opzione .7. $x = $array[count($array)-1];(a causa dell'uso dicount)
    • opzione .9. $x = $array[] = array_pop($array);(a causa dell'assegnazione di un valore che perde la chiave originale)
  • questa opzione non conserva il puntatore interno dell'array
    • opzione .5. $x = end($array); reset($array);
  • questa opzione è un tentativo di modificare l' opzione .5. per preservare il puntatore interno dell'array (ma purtroppo non si adatta bene per array molto grandi)
    • opzione .6. $x = end((array_values($array)));
  • la nuova array_key_lastfunzione sembra non avere nessuno dei limiti sopra menzionati, ad eccezione di essere ancora un RC al momento in cui scrivo (quindi usa l'RC o attendi il suo rilascio dicembre 2018):
    • opzione 10. $x = $array[array_key_last($array)]; (da PHP 7.3)

Un po 'a seconda che si usi l'array come stack o come coda è possibile apportare variazioni sull'opzione 9.


Se trovi una particolare opzione mancante, puoi provarla tu stesso copiando e incollando insieme i frammenti di codice di cui sopra, confrontandola con un'opzione precedentemente testata. Aggiungere un'opzione a questo elenco significherebbe ripetere il test di tutte le combinazioni per risultati di prestazioni comparabili. Se hai una particolare opzione che ritieni debba essere aggiunta, per favore lascia un commento, intendo aggiungerla (anche se potrebbe richiedere del tempo).
Paul van Leeuwen,

1
Ottima risposta, un commento però: per gli array associativi anche l'opzione 9 non può essere utilizzata, perché stiamo assegnando di nuovo una chiave autoindicizzata invece del nome della chiave precedente.
Gras Double,

1
Bel riassunto! Aggiungi la mia risposta usando il nuovo PHP 7.3. funzione $array[array_key_last($array)];per il tuo benchmark. E per favore dammi una notifica quando hai finito. Mi piacerebbe vedere i risultati delle prestazioni in confronto.
Clone di Quasimodo il

2
@sz è stato prodotto principalmente con molta testardaggine e pazienza, ma la selezione generale e le funzioni di modifica multilinea dell'editor di testo Sublime hanno aiutato. la rigenerazione ha richiesto quasi un giorno, quindi se dovessi farlo di nuovo probabilmente scriverò qualcosa che converte automaticamente l'output di tutte le 210 esecuzioni docker in una tabella :-)
Paul van Leeuwen,

1
@ quasimodos-clone Ho rigenerato l'intera tabella in base all'ultimo PHP 5, 7 rilasciato e al tuo RC. Suppongo che vorremmo generarlo di nuovo a dicembre, quando sarà effettivamente rilasciato. Grazie per aver portato questa nuova funzione all'attenzione di tutti.
Paul van Leeuwen,

487

Provare

$myLastElement = end($yourArray);

Per resettarlo (grazie @hopeseekr):

 reset($yourArray);

Link al manuale

@David Murdoch aggiunto: $myLastElement = end(array_values($yourArray));// and now you don't need to call reset(). Su E_STRICT questo produce l'avvertimento

Strict Standards: Only variables should be passed by reference

Grazie o_O Tync e tutti!


38
Usa $myLastElement = end(array_values($yourArray));e ora non hai bisogno di chiamare reset().
David Murdoch,

5
@DavidMurdoch Forse, ma sicuramente fa muovere RAM e CPU, creando l'array temporaneo per i valori dell'array ...
Theodore R. Smith

12
Se il tuo server sta consumando troppa RAM in modo che chiamare una semplice funzione extra sia un rompicapo, ti suggerisco di riesaminare la configurazione e le risorse del tuo server.
Chris Baker,

3
end(array_values())darà un E_STRICT: "Solo le variabili devono essere passate per riferimento"
kolypto

32
Aggiungi parentesi aggiuntiva per evitare il rigoroso avvertimento:end((array_values($yourArray)))
Daniel W.

212

Breve e dolce

Ho trovato una soluzione per rimuovere il messaggio di errore e preservare la forma di una riga e le prestazioni efficienti:

$lastEl = array_values(array_slice($array, -1))[0];

- soluzione precedente

$lastEl = array_pop((array_slice($array, -1)));

Nota: le parentesi extra sono necessarie per evitare a PHP Strict standards: Only variables should be passed by reference.


31
Dopo esattamente 5 anni, 6 mesi e 2 giorni, hai inviato una risposta più eccellente !! Grazie! e grazie Stack Overflow !!
Theodore R. Smith,

1
Saluta la risposta, ma l'aggiunta delle parentesi extra sembra un po 'hackisch. Anche phpStorm lo contrassegnerà come un errore. Informazioni extra per l'aggiunta di parentesi extra ( phpsadness.com/sad/51 ). Per superare l'errore, potresti renderlo un "2-liner": $array = array_slice($array, -1); $lastEl = array_pop($array);Personalmente penso che sia meglio (senza il "bug" del parser)
Maurice,

3
Puoi usare il dereferencing in questo modo: array_slice ($ array, -1) [0]
Vikash

1
Non puoi se hai stringhe come indice nell'array
rolacja

3
Questa risposta richiede ancora almeno due controlli per evitare le notifiche PHP. 1. verifica se array_size() > 1 2. Verifica se l'array è effettivamente un array. Mi attengo ancora alla risposta di @Iznogood poiché la end()funzione integrata di PHP svolge già tutto il duro lavoro in modo più efficiente.
Ema4rl,

37

Cosa c'è che non va array_slice($array, -1)? (Vedi manuale: http://us1.php.net/array_slice )

array_slice()restituisce un array. Probabilmente non quello che stai cercando. Vuoi l'elemento.


21
Utilizzare array_slice($array, -1)[0]per ottenere l'elemento.
Pang

2
Questa è la risposta "end" Modifica del puntatore interno dell'array? Chiedere guai e molto difficile da leggere!
Gerard ONeill,

Adoro questo approccio, anche se come sottolinea @Pang, non è del tutto completo. reset(array_slice($array, -1))è un altro approccio (che non causerà un errore se array_slice()restituisce qualcosa di "più piccolo" di un array a elemento singolo)
rinogo,

L'approccio migliore in quanto è possibile modificare direttamente l'elemento:array_slice($array, -1)[0] = "";
HAlex,

20

Un modo per evitare errori pass-by-reference (ad es. "End (array_values ​​($ foo))") è usare call_user_func o call_user_func_array:

// PHP Fatal error: Only variables can be passed by reference
// No output (500 server error)
var_dump(end(array(1, 2, 3)));

// No errors, but modifies the array's internal pointer
// Outputs "int(3)"
var_dump(call_user_func('end', array(1, 2, 3)));

// PHP Strict standards:  Only variables should be passed by reference
// Outputs "int(3)"
var_dump(end(array_values(array(1, 2, 3))));

// No errors, doesn't change the array
// Outputs "int(3)"
var_dump(call_user_func('end', array_values(array(1, 2, 3))));

Ottimo approccio! (inserisci qui lo standard "Questa dovrebbe essere la risposta accettata")
Typo

3
O semplicemente aggiungi una parantesi aggiuntiva. Più breve e più dolce:end((array_values($yourArray)))
Dzhuneyt,

4
Il trucco tra parentesi extra si basa su un bug in PHP e tale approccio non funziona più nelle versioni successive di PHP (o almeno non in PHP 7).
Matt Browne,

1
E il call_user_functrucco non funziona neanche in PHP 7. Penso che tu sia bloccato con la creazione di una variabile temporanea.
Matt Browne,

15

Se non ti interessa modificare il puntatore interno (supporta sia array indicizzati che associativi):

// false if empty array
$last = end($array);

// null if empty array
$last = !empty($array) ? end($array) : null;


Se si desidera una funzione di utilità che non modifica il puntatore interno (poiché l'array viene passato per valore e la funzione opera su una sua copia):

function array_last($array) {
    if (empty($array)) {
        return null;
    }
    return end($array);
}

Nota che PHP produce copie "al volo", cioè solo quando effettivamente necessarie. Lo end()stesso modifica l'array, quindi internamente viene generata una copia dell'array.


Pertanto, la seguente alternativa è in realtà più veloce in quanto internamente non copia l'array, ma solo una porzione:

function array_last($array) {
    if (empty($array)) {
        return null;
    }
    foreach (array_slice($array, -1) as $value) {
        return $value;
    }
}

Questo "foreach / return" è una modifica per ottenere in modo efficiente il primo (e qui singolo) elemento.


Infine, l'alternativa più veloce ma solo per array indicizzati:

$last = !empty($array) ? $array[count($array)-1] : null;



Per la cronaca, ecco un'altra mia risposta , per il primo elemento dell'array.


si forniscono 2 implementazioni alternative per una array_lastfunzione. Per il primo dichiari che $arrayè stato copiato e per il secondo che non è stato copiato. Dov'è la differenza / perché viene copiata nella prima implementazione e non nella seconda?
Paul van Leeuwen,

1
@PaulvanLeeuwen Ho capito perché ti sei confuso. Ho cercato di chiarire la risposta , è meglio?
Gras Double

10

non testato: non funzionerebbe?

<?php
$last_element=end(array_values($array));
?>

Poiché l'array restituito da array_values ​​è fugace, a nessuno importa se il puntatore viene ripristinato.

e se hai bisogno della chiave per accompagnarla, immagino che dovresti farlo:

<?php
$last_key=end(array_keys($array));
?>

9

Ho bisogno abbastanza spesso di gestire gli stack e mi trovo sempre sconcertato dal fatto che non esiste alcuna funzione nativa che lo fa senza manipolare l'array o il suo puntatore interno in qualche forma.

Quindi di solito porto in giro una funzione util che è anche sicura da usare su array associativi.

function array_last($array) {
    if (count($array) < 1)
        return null;

    $keys = array_keys($array);
    return $array[$keys[sizeof($keys) - 1]];
}

1
Buone notizie, la stanno trasformando in una funzione nativa :-) Puoi tenere d'occhio la sua pianificazione di rilascio qui: wiki.php.net/todo/php73 (atteso il 13 dicembre 2018 al momento in cui scrivo).
Paul van Leeuwen,

9

Per ottenere l'ultimo elemento di un array, utilizzare:

$lastElement = array_slice($array, -1)[0];

Prova delle prestazioni

Ho ripetuto 1.000 volte, afferrando l'ultimo elemento di array piccoli e grandi che contenevano rispettivamente 100 e 50.000 elementi.

Method: $array[count($array)-1];
Small array (s): 0.000319957733154
Large array (s): 0.000526905059814
Note: Fastest!  count() must access an internal length property.
Note: This method only works if the array is naturally-keyed (0, 1, 2, ...).

Method: array_slice($array, -1)[0];
Small array (s): 0.00145292282104
Large array (s): 0.499367952347

Method: array_pop((array_slice($array, -1, 1)));
Small array (s): 0.00162816047668
Large array (s): 0.513121843338

Method: end($array);
Small array (s): 0.0028350353241
Large array (s): 4.81077480316
Note: Slowest...

Ho usato la versione 5.5.3 di PHP.


che dire dell'uso di $ array [array_keys ($ array) [count (array_keys ($ array)) - 1]]?
user2782001,

hmm..array_keys sembra ridimensionarsi piuttosto male.
user2782001,

1
In realtà è follemente più veloce per l'array di grandi dimensioni (0,0002) estrarre l'elemento e rimetterlo su ... $ val = $ ar [] = $ array_pop ($ ar);
user2782001,

1
@ Westy92 Le tue unità sembrano sbagliate sul benchmark. Il numero più piccolo che dai è 0.00031 ... microsecondi che è circa 0,3 nanosecondi. Ciò significherebbe che il test ha richiesto un orologio per l'esecuzione se si dispone di un computer nuovo. Immagino che volevi dire millisecondi o forse anche secondi .
cesoide,

1
I valori sono chiaramente diversi ordini di grandezza sbagliati. Perché concentrarsi sulle prestazioni comunque?
istepaniuk,

6

end () fornirà l'ultimo elemento di un array

$array = array('a' => 'a', 'b' => 'b', 'c' => 'c');
echo end($array); //output: c

$array1 = array('a', 'b', 'c', 'd');
echo end($array1); //output: d

1
Questa soluzione funziona, ma cambia il puntatore interno dell'array, non credo sia nel modo giusto.
UnixAgain il

5

Dal PHP versione 7.3 le funzioni array_key_firsted array_key_lastè stato introdotto.

Poiché gli array in PHP non sono tipi di array rigorosi, ovvero raccolte di dimensioni fisse di campi di dimensioni fisse a partire dall'indice 0, ma array associativo esteso dinamicamente, la gestione delle posizioni con chiavi sconosciute è difficile e le soluzioni alternative non funzionano molto bene. Al contrario, gli array reali verrebbero indirizzati internamente tramite aritmetica del puntatore molto rapidamente e l'ultimo indice è già noto al momento della compilazione mediante dichiarazione.

Almeno il problema con la prima e l'ultima posizione è risolto dalle funzioni integrate ora dalla versione 7.3. Funziona anche senza alcun avvertimento sui letterali di array pronti all'uso :

$first = array_key_first( [1, 2, 'A'=>65, 'B'=>66, 3, 4 ] );
$last  = array_key_last ( [1, 2, 'A'=>65, 'B'=>66, 3, 4 ] );

Ovviamente l'ultimo valore è:

$array[array_key_last($array)];

1
Grazie per averlo portato all'attenzione di tutti. Per coloro che sono desiderosi di usare questo: per favore, non che questo sia un RC al momento in cui scrivo. L'uscita è prevista per dicembre 2018.
Paul van Leeuwen,

1
Questa è una grande notizia. Ho appena pubblicato un polyfill / shim nella mia risposta qui sotto in modo che le persone possano iniziare subito a usare questa sintassi.
Mark Thomson,

3
$lastValue = end(array_values($array))

Non viene apportata alcuna modifica ai puntatori $ array. Questo evita il

reset($array)

che potrebbe non essere desiderato in determinate condizioni.


3

Per me:

$last = $array[count($array) - 1];

Con i soci:

$last =array_values($array)[count($array - 1)]

Fornisci un contesto alla tua risposta.
Shawn,

2
@Shawn Quale contesto? Non ho bisogno di contesto. Codice aggiunto per array associativi.
Mirko Pagliai,

3

Le risposte migliori sono ottime, ma come menzionato da @ paul-van-leeuwen e @ quasimodos-clone, PHP 7.3 introdurrà due nuove funzioni per risolvere direttamente questo problema: array_key_first () e array_key_last () .

È possibile iniziare a utilizzare questa sintassi oggi con le seguenti funzioni polyfill (o shim).

// Polyfill for array_key_last() available from PHP 7.3
if (!function_exists('array_key_last')) {
  function array_key_last($array) {
    return array_slice(array_keys($array),-1)[0];
  }
}

// Polyfill for array_key_first() available from PHP 7.3
if (!function_exists('array_key_first')) {
  function array_key_first($array) {
    return array_slice(array_keys($array),0)[0];
  }
}

// Usage examples:
$first_element_key   = array_key_first($array);
$first_element_value = $array[array_key_first($array)];

$last_element_key    = array_key_last($array);
$last_element_value  = $array[array_key_last($array)];

Avvertenza: richiede PHP 5.4 o versioni successive.


2

Per fare ciò ed evitare E_STRICT e non pasticciare con il puntatore interno dell'array puoi usare:

function lelement($array) {return end($array);}

$last_element = lelement($array);

lelement funziona solo con una copia, quindi non influisce sul puntatore dell'array.


2

Un'altra soluzione:

$array = array('a' => 'a', 'b' => 'b', 'c' => 'c');
$lastItem = $array[(array_keys($array)[(count($array)-1)])];
echo $lastItem;

2

Un'altra soluzione possibile ...

$last_element = array_reverse( $array )[0];

Non lavorare su array associativi non sembra una ragione sufficiente per sottovalutarmi. Per quanto riguarda la qualità, questa risposta non è peggiore di molte altre risposte a questa domanda. Non capisco perché vedo almeno 2 voti negativi in ​​questo momento. (punteggio di -2). Comunque, voto positivo per me, non è poi così male.
Paul van Leeuwen,

2

Che ne dite di:

current(array_slice($array, -1))
  • lavora per array associativi
  • funziona quando $array == [](ritorna false)
  • non influisce sull'array originale

2

Otterrai facilmente l'ultimo elemento da un array usando la logica seguente

$array = array('a', 'b', 'c', 'd');
echo ($array[count($array)-1]);

Non solo l'ultimo elemento, ma puoi anche ottenere il secondo ultimo, il terzo ultimo e così via usando la logica di seguito.

per il secondo ultimo elemento devi passare solo il numero 2 nell'istruzione precedente, ad esempio:
echo ($ array [count ($ array) -2]);


1

Per ottenere l'ultimo valore dall'array:

array_slice($arr,-1,1) ;

Per la rimozione dell'array modulo ultimo valore:

array_slice($arr,0,count($arr)-1) ;

1
array_slice($arr,-1,1)risulterà in un altro array con lunghezza 1, non l'ultimo elemento
Vic

Facciamo un esempio: $a=array("red","green","blue","yellow","brown"); print_r(array_slice($a,-1,1)); Risultato:Array ( [0] => brown )
Rishabh

1

Semplicemente: $last_element = end((array_values($array)))

Non reimposta l'array e non fornisce avvisi STRICT.

PS. Poiché la risposta più votata non ha ancora la doppia parentesi, ho inviato questa risposta.


1

Penso che questo sia un leggero miglioramento su tutte le risposte esistenti:

$lastElement = count($array) > 0 ? array_values(array_slice($array, -1))[0] : null;
  • Offre prestazioni migliori rispetto alle end()soluzioni o array_keys(), in particolare, con array di grandi dimensioni
  • Non modificherà il puntatore interno dell'array
  • Non tenterà di accedere a un offset indefinito per array vuoti
  • Funzionerà come previsto per array vuoti, array indicizzati, array misti e array associativi

Purtroppo non funziona con le matrici associative, poiché l'elemento singolo della sezione potrebbe avere una chiave con nome.
Gras Double,

Hai ragione, modificato per aggiungere una correzione ( array_valuessulla porzione a elemento singolo)
Adelmar,


1

Oggi preferirei avere sempre questo aiuto, come suggerito in una risposta php.net/end .

<?php
function endc($array) {
    return end($array);
}

$items = array('one','two','three');
$lastItem = endc($items); // three
$current = current($items); // one
?>

Ciò manterrà sempre il puntatore così com'è e non dovremo mai preoccuparci di parentesi, standard rigorosi o altro.


Già accennato in precedenza: stackoverflow.com/a/45333947/1255289
miken32


-1

Cosa succede se si desidera ottenere l'ultimo elemento dell'array all'interno del ciclo del suo array?

Il codice seguente si tradurrà in un ciclo infinito:

foreach ($array as $item) {
 $last_element = end($array);
 reset($array);
 if ($last_element == $item) {
   // something useful here
 }
}

La soluzione è ovviamente semplice per gli array non associativi:

$last_element = $array[sizeof ($array) - 1];
foreach ($array as $key => $item) {
 if ($last_element == $item) {
   // something useful here
 }
}

2
Conosco le funzioni end () e reset (). Il mio commento era correlato a loop come foreach o mentre non è possibile utilizzare queste funzioni perché la funzione reset reimposta il puntatore interno di un array che viene utilizzato nel ciclo per l'iterazione. Scusatemi, la domanda era più semplice, volevo solo dare una situazione più avanzata che mi sono imbattuto nel mio progetto. I migliori saluti.
Vadim Podlevsky,

Questo è sbagliato in molti modi (array con duplicati, confronto non rigoroso ...) e comunque non realmente correlato alla domanda.
Tgr,

usa la funzione end ($ array) per ottenere l'ultimo elemento, perché usi inutilmente dei loop?
Mahak Choudhary,

1
@MahakChoudhary Il mio commento è un'aggiunta a "come ottenere l'ultimo elemento dell'array se stai facendo alcune manipolazioni già all'interno di un loop di questo array. L'uso di end () ripristinerà il puntatore innver e interromperà il ciclo di iterazione. Saluti!
Vadim Podlevsky

-1
$file_name_dm =  $_FILES["video"]["name"];    

                           $ext_thumb = extension($file_name_dm);

                            echo extension($file_name_dm); 
function extension($str){
    $str=implode("",explode("\\",$str));
    $str=explode(".",$str);
    $str=strtolower(end($str));
     return $str;
}



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.