Come ottenere l'ultima chiave in un array?


Risposte:


610

Una soluzione sarebbe quella di utilizzare una combinazione di ende (citazione) :key

  • end() fa avanzare il puntatore interno dell'array all'ultimo elemento e ne restituisce il valore.
  • key() restituisce l'elemento indice della posizione corrente dell'array.

Quindi, una parte di codice come questa dovrebbe fare il trucco:

$array = array(
    'first' => 123,
    'second' => 456,
    'last' => 789, 
);

end($array);         // move the internal pointer to the end of the array
$key = key($array);  // fetches the key of the element pointed to by the internal pointer

var_dump($key);

Uscita:

string 'last' (length=4)

cioè la chiave dell'ultimo elemento del mio array.

Al termine, il puntatore interno dell'array si troverà alla fine dell'array. Come sottolineato nei commenti, potresti voler eseguire reset()l'array per riportare il puntatore all'inizio dell'array.


17
@Pim: dipende da ciò che l'OP vuole fare con quell'array dopo (potrebbe non essere necessario chiamare reset()) ;; ma hai ragione nel puntare quella funzione, che potrebbe essere utile.
Pascal MARTIN,

3
@PascalMARTIN +1 Penso che aggiungere un commento sul reset () nella tua risposta sarà molto utile.
Lulu,

Questo approccio non funziona se l'array ha valori duplicati. per esempio. poiché array('a', 'b', 'c', 'd', 'a')restituirà la chiave 0 anziché 4.
Marc

2
@Marc questo approccio funziona correttamente anche se ci sono valori duplicati.
Jeff

1
@pppp non funziona perché ... controlla cosa restituisce end () e poi ripensaci;)
forsberg

79

Anche se end()sembra essere il più semplice, non è il più veloce. L'alternativa più veloce e molto più forte è array_slice():

$lastKey = key(array_slice($array, -1, 1, true));

Come dicono i test , su un array con 500000 elementi, è quasi 7 volte più veloce!


98
eccitato da questa risposta, ho fatto un rapido test di 100.000 iterazioni, confrontando (a) end($arr);$key = key($arr);reset($arr);con (b) $key = key(array_slice($arr,-1,1,true));... risultando end()MOLTO più veloce! end () = 0,05326 secondi, array_slice = 8.506 secondi ... eh ??
neokio,

54
Le funzioni integrate di PHP sono state costruite da nerd estremi. Non provare a ricreare quelle funzioni. Le probabilità sono che tu realizzi qualcosa di molto più lento dell'originale. A meno che tu non sia una specie di mago malvagio, di couse.
dmmd

16
end()è più veloce perché può essere derivato da una funzione C molto semplice, come ad esempio:int top(void){ int i; for(i = 0; stack[i] != '\0'; i++); return stack[--i]; }
Gustav,

10
@Gustav Credo che l'implementazione C sottostante di PHP, in realtà abbia un puntatore interno lastall'ultimo elemento. Facendo end()praticamente O (1). :-)
Eric

15
@dmmd, sono sicuro che il team di PHP sarebbe estremamente contento di essere chiamati nerd.
datasn.io,

53

preferisco

end(array_keys($myarr))

19
causa AVVISO STRETTO, fine si aspetta un riferimento variabile
Wiliam

25
Puoi usare end((array_keys($myarr)))per aggirare l'avviso.
Ben Fortune,

9
@BenFortune Questo problema è stato risolto in PHP7: "In PHP 5, l'uso di parentesi ridondanti attorno a un parametro di funzione potrebbe mettere a tacere avvisi di standard rigidi quando il parametro di funzione viene passato per riferimento. L'avviso verrà ora sempre emesso."
Dominic Scheirlinck il

questo è un avvertimento totalmente inutile! è roba così normale e normale in tutte le altre lingue!
Azerafati,

1
In altre lingue, le funzioni non funzionano sui puntatori, vero?
Jurchiks,

52

Da PHP 7.3 (2018) esiste (finalmente) una funzione per questo: http://php.net/manual/en/function.array-key-last.php

$array = ['apple'=>10,'grape'=>15,'orange'=>20];
echo array_key_last ( $array )

uscirà

orange

4
Horray! Stavo per aggiungere questa risposta. Potresti evidenziare la versione "PHP 7.3" e l'anno 2018? Sarà più facile individuare questa fantastica notizia per gli altri
Tomáš Votruba il

Va anche detto che ciò NON influisce sul puntatore di array interno.
mvorisek,

30

Usa solo: echo $array[count($array) - 1];


75
Funziona solo se si hanno array numerici. Errore con le matrici associate.
Jeremy J Starcher,

12
Non funziona solo su array numerici, ma non mostra la chiave ma mostra il valore, no?
Nanne,

anche io jake, possiamo fare una cosa in cui abbiamo diviso questo hit (diciamolo sincero) in Google sia numerico che associativo in modo che abbiamo un vecchio riferimento per entrambi ... Ho capito che era solo per assoc dopo l'analisi int top(void){ int i; for(i = 0; stack[i] != '\0'; i++); return stack[--i]; }che è interessante ma non buono per gli affari quando hai un budget limitato
lol

5
Inoltre, anche per un array numerico, tieni presente che gli array numerici non devono andare in ordine o utilizzare tutti i numeri. Questo funzionerà se non si assegna esplicitamente a valori numerici, ma se lo si fa $a[1] = 1; $a[5] = 5; $a[0] = 0;Quindi si avrà un array con le chiavi (1, 5, 0), in questo ordine. count($a)produrrà 3 e $a[2]non è definito. Certamente non ti restituisce 5.
Daniel Skarbek,

1
Leggi di nuovo la domanda "Come ottenere l'ultima chiave in un array?"

20

Non so se questo sarà più veloce o meno, ma sembra più facile farlo in questo modo ed eviti l'errore non passando una funzione a end () ...

aveva solo bisogno di una variabile ... non è un grosso problema per scrivere un'altra riga di codice, quindi disinserirla se necessario.

$array = array(
    'first' => 123,
    'second' => 456,
    'last' => 789, 
);

$keys = array_keys($array);
$last = end($keys);

2
Questa risposta (sebbene tecnicamente corretta) è dispendiosa / inefficiente perché richiede la creazione di un array aggiuntivo (della stessa lunghezza dell'originale). Ciò significa che lo spreco aumenta come l'array originale. Questo non dovrebbe mai essere scelto sulla risposta efficiente di Pascal MARTIN. Sono sorpreso che questo abbia tanti voti positivi.
mickmackusa,

12

A partire da PHP7.3 puoi accedere direttamente all'ultima chiave (il livello esterno di) un array con array_key_last ()

Mette definitivamente a dura prova gran parte del dibattito in questa pagina. È senza dubbio il miglior esecutore, non subisce effetti collaterali ed è una tecnica diretta, intuitiva, a chiamata singola per fornire esattamente ciò che questa domanda cerca.

Un punto di riferimento approssimativo come prova: https://3v4l.org/hO1Yf

array_slice() + key():  1.4
end() + key():         13.7
array_key_last():       0.00015

* l'array di test contiene 500000 elementi, microtime ripetuto 100x quindi mediato quindi moltiplicato per 1000 per evitare la notazione scientifica. Ringraziamo @MAChitgarha per il benchmark iniziale commentato nella risposta di @ TadejMagajna .

Ciò significa che puoi recuperare il valore della chiave finale senza:

  1. spostando il puntatore dell'array (che richiede due righe di codice) o
  2. smistamento, inversione, apertura, conteggio, indicizzazione di una serie di chiavi o di qualsiasi altra stupidaggine

Questa funzione era attesa da tempo e una gradita aggiunta alla cintura degli strumenti della funzione array che migliora le prestazioni, evita effetti collaterali indesiderati e consente codice pulito / diretto / intuitivo.

Ecco una demo :

$array = ["a" => "one", "b" => "two", "c" => "three"];
if (!function_exists('array_key_last')) {
    echo "please upgrade to php7.3";
} else {
    echo "First Key: " , key($array) , "\n";
    echo "Last Key: " , array_key_last($array) , "\n";
    next($array);                 // move array pointer to second element
    echo "Second Key: " , key($array) , "\n";
    echo "Still Last Key: " , array_key_last($array);
}

Produzione:

First Key: a
Last Key: c     // <-- unaffected by the pointer position, NICE!
Second Key: b
Last Key: c     // <-- unaffected by the pointer position, NICE!

Alcune note:

  • array_key_last()è la funzione di pari livello di array_key_first () .
  • Entrambe queste funzioni sono "puntatore-ignorante".
  • Entrambe le funzioni ritornano null se l'array è vuoto.
  • Anche le funzioni di fratelli scartati ( array_value_first()& array_value_last()) avrebbero offerto agli ignoranti un accesso puntatore-ignorante agli elementi, ma evidentemente non sono riuscite a ottenere voti sufficienti per prendere vita.

Ecco alcune pagine pertinenti che parlano delle nuove funzionalità:

ps Se qualcuno sta valutando alcune delle altre tecniche, puoi fare riferimento a questa piccola raccolta di confronti: ( Demo )

Duration of array_slice() + key():     0.35353660583496
Duration of end() + key():             6.7495584487915
Duration of array_key_last():          0.00025749206542969
Duration of array_keys() + end():      7.6123380661011
Duration of array_reverse() + key():   6.7875385284424
Duration of array_slice() + foreach(): 0.28870105743408

2
Questa risposta dovrebbe essere in cima all'elenco. È semplicemente completo.
Giovanni

1
Wow, un DV su QUESTA mia risposta? Qual era il problema, troppo completo / definitivo / esplicativo / supportato? Pfft. Sicuramente continua a spingere verso il basso i post che hanno il coraggio di informare. Buon lavoro. Nel caso non lo sapessi, il pulsante DV è per i post "non utili". Per favore, chiediti qual è il tuo obiettivo qui.
mickmackusa,

8

Prova a utilizzare la funzione array_pop e array_keys come segue:

<?php

$array = array(
    'one' => 1,
    'two' => 2,
    'three' => 3
);

echo array_pop(array_keys($array)); // prints three

?>

14
Questo è molto lento se l'array contiene più di 1 cosa. Per favore, non farlo.
Andrey,

3
e causa anche STRICT AVVISO, riferimento variabile
Wiliam

array_pop () accorcerebbe l'array originale (rimuovendo l'ultimo elemento). Non sono sicuro se questo sia importante o meno per il PO, ma sarà sicuramente importante per gli altri.
Programmatore

1
Non proprio. In questo esempio array_pop()opera sul valore restituito array_keys()e non sull'array originale.
Petko Bossakov,

Poiché esistono altre risposte più efficienti che non attivano un AVVISO, sto annullando il voto a questa risposta.
Mickmackusa,

6

A partire da PHP> = 7.3 array_key_last()è il modo migliore per ottenere l'ultima chiave di uno qualsiasi di un array. Utilizzando combinazione di end(), key()e reset()solo per ottenere ultima chiave di un array è scandaloso.

$array = array("one" => bird, "two" => "fish", 3 => "elephant");
$key = array_key_last($array);
var_dump($key) //output 3

confrontalo con

end($array)
$key = key($array)
var_dump($key) //output 3
reset($array)

È necessario reimpostare l'array affinché il puntatore sia all'inizio se si utilizza la combinazione di end()ekey()


4

Vorrei anche offrire una soluzione alternativa a questo problema.

Supponendo che tutte le chiavi siano numeriche senza spazi vuoti, il mio metodo preferito è contare l'array quindi meno 1 da quel valore (per tenere conto del fatto che le chiavi dell'array iniziano da 0.

$array = array(0=>'dog', 1=>'cat');

$lastKey = count($array)-1;
$lastKeyValue = $array[$lastKey];

var_dump($lastKey);
print_r($lastKeyValue);

Questo ti darebbe:

int (1) cat


1
Ciò non funzionerà per gli array in cui le chiavi non sono incrementali, ad esempio array (0 => 'dog', 5 => 'cat'); $ lastKey restituirebbe un valore errato
kakoma,

@kakoma - Come dice il mio post "Supponendo che tutte le tue chiavi siano numeriche senza spazi vuoti".

Per chiunque si chieda, usa "array_values" di PHP per ricodificare l'array in sequenza numerica. php.net/manual/en/function.array-values.php

1
Poiché questa risposta riguarda solo una frazione delle possibilità dell'array (array numerici, con chiave consecutiva), questa risposta non offre una risposta solida / corretta alla domanda generalizzata del PO. Downvote.
Mickmackusa,

4

Puoi usare questo:

$array = array("one" => "apple", "two" => "orange", "three" => "pear");
end($array); 
echo key($array);

Un'altra soluzione è creare una funzione e usarla:

function endKey($array){
end($array);
return key($array);
}

$array = array("one" => "apple", "two" => "orange", "three" => "pear");
echo endKey($array);

1
Questa risposta non fornisce nulla di nuovo che non sia già presente in questa discussione.
Martin,

1
Martin, nessuno usa la funzione per ottenere il risultato.
Atif Tariq,

1
devi aggiungere 1 riga di codice in una funzione? È un'interfaccia piuttosto inutile.
Martin,

1
Martin, che una riga.
Atif Tariq,

2
la linea nella tua funzione
Martin

3
$arr = array('key1'=>'value1','key2'=>'value2','key3'=>'value3');
list($last_key) = each(array_reverse($arr));
print $last_key;
// key3

2
Invertire l'intero array solo per estrarre un valore è sicuramente meno efficiente del metodo PascalMARTIN. Anche se tecnicamente corretto, non dovrebbe mai essere usato al posto dell'approccio di Pascal.
mickmackusa,

3

Ho appena preso la funzione di supporto da Xander e l'ho migliorata con le risposte prima:

function last($array){
  $keys = array_keys($array);
  return end($keys);
}


$arr = array("one" => "apple", "two" => "orange", "three" => "pear");    
echo last($arr);
echo $arr(last($arr));

1

Prova questo con array_reverse().

 $arr = array(
     'first' => 01,
     'second' => 10,
     'third' => 20, 
 );  
 $key = key(array_reverse($arr));
 var_dump($key);

1

È strano, ma perché questo argomento non ha questa risposta:

$lastKey = array_keys($array)[count($array)-1];


0
$array = array(
    'something' => array(1,2,3),
    'somethingelse' => array(1,2,3,4)
);

$last_value = end($array);
$last_key = key($array); // 'somethingelse'

Questo funziona perché PHP sposta internamente il puntatore dell'array per $ array


2
Questo è un duplicato del metodo di PascalMARTIN. Per favore risparmia questa pagina ed elimina la tua risposta tardiva / duplicata. Downvoted.
mickmackusa,

0

La migliore soluzione possibile che può essere utilizzata anche in linea:

end($arr) && false ?: key($arr)

Questa soluzione è solo espressione / affermazione e garantisce che non sia la migliore prestazione possibile.

Esempio di utilizzo in linea:

$obj->setValue(
    end($arr) && false ?: key($arr) // last $arr key
);


AGGIORNAMENTO: In PHP 7.3+: usa (ovviamente) il array_key_last()metodo appena aggiunto .

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.