¿Cómo obtener la última clave en una matriz?

335

¿Cómo puedo obtener la última clave de una matriz?

ajsie
fuente
10
Debe especificar una matriz asociativa, una matriz numérica o si tiene que funcionar en ambas.
Jimbo Jonny
pregunta frecuente
Josua Marcel Chrisano

Respuestas:

610

Una solución sería usar una combinación de endy (citando) :key

  • end() avanza el puntero interno de la matriz al último elemento y devuelve su valor.
  • key() devuelve el elemento índice de la posición actual de la matriz.

Entonces, una porción de código como este debería hacer el truco:

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

Saldrá:

string 'last' (length=4)

es decir, la clave del último elemento de mi matriz.

Una vez hecho esto, el puntero interno de la matriz estará al final de la matriz. Como se señaló en los comentarios, es posible que desee ejecutar reset()en la matriz para que el puntero regrese al comienzo de la matriz.

Pascal MARTIN
fuente
17
@Pim: depende de lo que el OP quiera hacer con esa matriz después (puede que no sea necesario llamar reset()) ; pero tienes razón al señalar esa función, que podría ser útil.
Pascal MARTIN
3
@PascalMARTIN +1 Creo que agregar un comentario sobre reset () en su respuesta será muy útil.
Lulu
Este enfoque no funciona si la matriz tiene valores duplicados. p.ej. porque array('a', 'b', 'c', 'd', 'a')devolverá la clave 0 en lugar de 4.
Marc
2
@Marc este enfoque funciona correctamente incluso si hay un valor duplicado.
Jeff
1
@pppp no ​​funciona porque ... comprueba qué end () regresa y luego piensa de nuevo;)
forsberg
79

Aunque end()parece ser el más fácil, no es el más rápido. La alternativa más rápida y mucho más fuerte es array_slice():

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

Como dicen las pruebas , en una matriz con 500000 elementos, ¡es casi 7 veces más rápido!

Tadej Magajna
fuente
98
entusiasmado por esta respuesta, hice una prueba rápida de 100,000 iteraciones, comparando (a) end($arr);$key = key($arr);reset($arr);con (b) $key = key(array_slice($arr,-1,1,true));... ¡lo que resultó en end()MUCHO más rápido! end () = 0.05326 segundos, array_slice = 8.506 segundos ... ¿eh?
neokio
54
Las funciones integradas de PHP fueron creadas por nerds extremos. No intentes recrear esas funciones. Lo más probable es que hagas algo mucho más lento que el original. A menos que seas una especie de mago malvado, por supuesto.
dmmd
16
end()es más rápido porque puede derivarse de una función C muy simple, como:int top(void){ int i; for(i = 0; stack[i] != '\0'; i++); return stack[--i]; }
Gustav
10
@Gustav Creo que la implementación C subyacente de PHP, en realidad tiene un puntero interno lastal último elemento. Haciendo más end()o menos O (1). :-)
Eric
15
@dmmd, estoy seguro de que el equipo de PHP estaría encantado de que se les llame nerds.
datasn.io
53

yo prefiero

end(array_keys($myarr))
Rutger van Baren
fuente
19
causa ESTRICTO AVISO, final espera una referencia variable
Wiliam
25
Puede usar end((array_keys($myarr)))para evitar el aviso.
Ben Fortune
99
@BenFortune Esto se ha solucionado en PHP7: "En PHP 5, el uso de paréntesis redundantes alrededor de un parámetro de función podría silenciar las advertencias de estándares estrictos cuando el parámetro de función se pasó por referencia. La advertencia ahora siempre se emitirá".
Dominic Scheirlinck
¡Esa es una advertencia totalmente innecesaria! ¡Es algo tan normal y habitual en todos los demás idiomas!
azerafati
1
En otros idiomas, las funciones no funcionan en punteros, ¿verdad?
jurchiks
52

Desde PHP 7.3 (2018) hay (finalmente) una función para esto: http://php.net/manual/en/function.array-key-last.php

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

saldrá

orange
Patryk Godowski
fuente
44
Horray! Estaba a punto de agregar esta respuesta. ¿Podría destacar la versión "PHP 7.3" y el año 2018? Será más fácil detectar esta increíble noticia para los demás
Tomáš Votruba
También es bueno mencionar que esto NO afecta el puntero interno de la matriz.
mvorisek
30

Solo usa : echo $array[count($array) - 1];

Aditya Choudhary
fuente
75
Esto solo funciona si tienes matrices numéricas. Falla con las matrices asociadas.
Jeremy J Starcher
12
Esto no solo funciona en matrices numéricas, sino que no muestra la clave sino que muestra el valor, ¿no?
Nanne
Yo también, Jake, ¿podemos hacer algo en lo que dividimos este éxito de Google (seamos honestos) en numérico y asociativo para que tengamos una referencia antigua para ambos ... Solo descubrí que era para la asociación después de analizar, int top(void){ int i; for(i = 0; stack[i] != '\0'; i++); return stack[--i]; }que es interesante pero no es bueno para los negocios cuando tienes poco presupuesto
lol
55
Además, incluso para una matriz numérica, tenga en cuenta que las matrices numéricas no tienen que ir en orden o usar todos los números. Esto funcionará si no asigna explícitamente valores numéricos, pero si lo hace $a[1] = 1; $a[5] = 5; $a[0] = 0;Entonces tendrá una matriz con las teclas (1, 5, 0), en ese orden. count($a)rendirá 3 y $a[2]no está definido. Ciertamente no te devuelve 5.
Daniel Skarbek
1
Lea la pregunta nuevamente "¿Cómo obtener la última clave en una matriz?"
20

No sé si esto va a ser más rápido o no, pero parece más fácil hacerlo de esta manera, y evita el error al no pasar una función para finalizar () ...

solo necesitaba una variable ... no es un gran problema para escribir una línea más de código, luego desarmarla si fuera necesario.

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

$keys = array_keys($array);
$last = end($keys);
Ryan Hungate
fuente
2
Esta respuesta (aunque técnicamente correcta) es inútil o ineficiente porque requiere la creación de una matriz adicional (de igual longitud que la original). Esto significa que el desperdicio aumenta a medida que lo hace la matriz original. Esto nunca debe elegirse sobre la respuesta eficiente de Pascal MARTIN. Me sorprende que esto tenga tantos votos positivos.
mickmackusa
12

A partir de PHP7.3 , puede acceder directamente a la última clave en (el nivel externo de) una matriz con array_key_last ()

El definitivamente pone gran parte del debate en esta página a la cama. Es, sin lugar a dudas, el mejor intérprete, no sufre efectos secundarios y es una técnica directa, intuitiva y de una sola llamada para entregar exactamente lo que esta pregunta busca.

Un punto de referencia aproximado como prueba: https://3v4l.org/hO1Yf

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

* La matriz de prueba contiene 500000 elementos, el microtiempo se repite 100 veces, luego se promedia y luego se multiplica por 1000 para evitar la notación científica. Gracias a @MAChitgarha por el punto de referencia inicial comentado bajo la respuesta de @ TadejMagajna .

Esto significa que puede recuperar el valor de la clave final sin:

  1. moviendo el puntero de matriz (que requiere dos líneas de código) o
  2. ordenar, invertir, hacer estallar, contar, indexar un conjunto de claves o cualquier otra tontería

Esta función se había retrasado mucho tiempo y era una adición bienvenida al cinturón de herramientas de la función de matriz que mejora el rendimiento, evita los efectos secundarios no deseados y permite un código limpio / directo / intuitivo.

Aquí hay una demostración :

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

Salida:

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

Algunas notas:

  • array_key_last()es la función hermana de array_key_first () .
  • Ambas funciones son "ignorantes de puntero".
  • Ambas funciones regresan null si la matriz está vacía.
  • Las funciones de hermanos descartados ( array_value_first()& array_value_last()) también habrían ofrecido el acceso ignorante del puntero a los elementos de sujetalibros, pero evidentemente no lograron obtener suficientes votos para cobrar vida.

Aquí hay algunas páginas relevantes que discuten las nuevas características:

ps Si alguien está evaluando algunas de las otras técnicas, puede consultar esta pequeña colección de comparaciones: ( 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
mickmackusa
fuente
2
Esta respuesta debe estar en la parte superior de la lista. Es simplemente completo.
John
1
Wow, un DV en esta respuesta mía? ¿Cuál fue el problema, demasiado completo / definitivo / explicativo / apoyado? No. Definitivamente continúen presionando las publicaciones que se atreven a informar. Buen trabajo. En caso de que no lo sepas, el botón DV es para publicaciones que "no son útiles". Pregúntese cuál es su objetivo aquí.
mickmackusa
8

Intente usar la función array_pop y array_keys de la siguiente manera:

<?php

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

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

?>
codictorio
fuente
14
Esto es realmente lento si su matriz tiene más de 1 cosa. Por favor no hagas esto.
Andrey
3
y causa AVISO ESTRICTO también, referencia variable
Wiliam
array_pop () acortaría la matriz original (eliminando el último elemento). No estoy seguro de si esto es importante o no para el OP, pero ciertamente será importante para los demás.
Programador
1
Realmente no. En este ejemplo array_pop()opera en el valor de retorno de array_keys()y no en la matriz original.
Petko Bossakov
Debido a que hay otras respuestas más eficientes que no activan un AVISO, rechazo esta respuesta.
mickmackusa
6

A partir de PHP> = 7.3 array_key_last()es la mejor manera de obtener la última clave de cualquiera de una matriz. Usar la combinación de end(), key()y reset()solo para obtener la última clave de una matriz es indignante.

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

compara eso con

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

Debe restablecer la matriz para que el puntero esté al principio si está utilizando una combinación de end()ykey()

Hilary Okoro
fuente
4

También me gustaría ofrecer una solución alternativa a este problema.

Suponiendo que todas sus claves son numéricas sin espacios, mi método preferido es contar la matriz y luego menos 1 a partir de ese valor (para tener en cuenta el hecho de que las claves de la matriz comienzan en 0.

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

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

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

Esto te daría:

int (1) gato


fuente
1
Esto no funcionará para las matrices donde las claves no son incrementales, por ejemplo, matriz (0 => 'perro', 5 => 'gato'); $ lastKey devolvería un valor incorrecto
kakoma
@kakoma - Como dice mi publicación "Suponiendo que todas sus claves sean numéricas sin espacios".
Para cualquiera que se pregunte, use "array_values" de PHP para volver a escribir la matriz en secuencial numérica. php.net/manual/en/function.array-values.php
1
Debido a que esta respuesta solo trata con una fracción de las posibilidades de la matriz (matrices numéricas consecutivas con clave), esta respuesta no ofrece una respuesta robusta / correcta a la pregunta generalizada del OP. Voto a favor.
mickmackusa
4

Puedes usar esto:

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

Otra solución es crear una función y usarla:

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

$array = array("one" => "apple", "two" => "orange", "three" => "pear");
echo endKey($array);
Atif Tariq
fuente
1
Esta respuesta no proporciona nada nuevo que no esté ya en este hilo.
Martin
1
Martin, nadie usa la función para obtener el resultado.
Atif Tariq
1
¿necesita agregar 1 línea de código en una función? Esa es una interfaz bastante innecesaria.
Martin
1
Martin, cuál línea.
Atif Tariq
2
la línea en tu función
Martin
3
$arr = array('key1'=>'value1','key2'=>'value2','key3'=>'value3');
list($last_key) = each(array_reverse($arr));
print $last_key;
// key3
voodoo417
fuente
2
Invertir toda la matriz solo para obtener un valor es ciertamente menos eficiente que el método de PascalMARTIN. Aunque es técnicamente correcto, nunca debe usarse en lugar del enfoque de Pascal.
mickmackusa
3

Acabo de tomar la función de ayuda de Xander y la mejoré con las respuestas anteriores:

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));
Steve
fuente
1

Prueba este con array_reverse().

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

Es extraño, pero por qué este tema no tiene esta respuesta:

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

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

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

Esto funciona porque PHP mueve su puntero de matriz internamente para $ array

Scottymeuk
fuente
2
Este es un duplicado del método de PascalMARTIN. Ahorre esta página y elimine su respuesta tardía / duplicada. Voto negativo
mickmackusa
0

La mejor solución posible que también se puede usar en línea:

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

Esta solución es solo expresión / declaración y proporciona buena no es el mejor rendimiento posible.

Ejemplo de uso en línea:

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


ACTUALIZACIÓN: En PHP 7.3+: use (por supuesto) el array_key_last()método recién agregado .

mvorisek
fuente