¿Cuál es la mejor manera de obtener el último elemento de una matriz sin eliminarlo?

427

Okay,

Lo sé todo array_pop(), pero eso elimina el último elemento. ¿Cuál es la mejor manera de obtener el último elemento de una matriz sin eliminarlo?

EDITAR: Aquí hay una bonificación:

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

o incluso

$array = array('a', 'b', 'c', 'd');
unset($array[2]);
echo $array[sizeof($array) - 1]; // Output: PHP Notice:  Undefined offset:  2 in - on line 4
Theodore R. Smith
fuente
11
Lo creas o no lo revientes y lo vuelvas a poner es una de las formas más rápidas en las que comparé esto. $ val = $ array [] = array_pop ($ array); echo $ val;
user2782001
2
Esta pregunta resultó en muchas opciones. Para ayudarme a elegir, hice una comparación de las opciones más notables / distintas y compartí los resultados como una respuesta separada . (: @ user2782001 sugirió mi favorito hasta ahora en el comentario anterior. :) ¡Gracias a todos por contribuir!
Paul van Leeuwen
1
@TheodoreRSmith Cuando PHP 7.3 se libera usted podría considerar la posibilidad de ( esta sugerencia por el clon de Quasimodo la 'respuesta aceptada' (para su consideración) ...
Paul van Leeuwen

Respuestas:

176

Las muchas respuestas en este hilo nos presentan muchas opciones diferentes. Para poder elegir entre ellos, necesitaba comprender su comportamiento y desempeño. En esta respuesta voy a compartir mis resultados con usted, se comparan contra las versiones de PHP 5.6.38, 7.2.10y 7.3.0RC1( se espera Dic 13 2018 ).

Las opciones <<option code>>que probaré son:

(funciones mencionadas: array_key_last , array_keys , array_pop , array_slice , array_values , count , end , reset )

Las entradas de prueba <<input code>>para combinar con:

  • nulo =$array = null;
  • vacío =$array = [];
  • last_null =$array = ["a","b","c",null];
  • auto_idx =$array = ["a","b","c","d"];
  • barajar =$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; }

Para el ensayo de I a utilizar el 5.6.38, 7.2.10y 7.3.0RC1 contenedores acoplables PHP como:

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

Cada combinación de los anteriores figuran <<option code>>s y <<input code>>s se llevará a cabo en todas las versiones de PHP. Para cada prueba ejecutada se utiliza el siguiente fragmento de código:

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

Para cada ejecución, esto variará el último último valor recuperado de la entrada de prueba e imprimirá la duración promedio de una iteración en femtosegundos (0.000000000000001 de segundo).

Los resultados son los siguientes:

/==========================================================================================================================================================================================================================================================================================================================================================================================================================\
||                                                                      ||                            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 ||
 \=========================================================================================================================================================================================================================================================================================================================================================================================================================/ 

La anteriormente mencionada F Atal, W Arning y N Otice códigos traducen como:

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

En base a este resultado, saco las siguientes conclusiones:

  • Las versiones más nuevas de PHP funcionan mejor con la excepción de estas opciones que se volvieron significativamente más lentas:
    • opción .6. $x = end((array_values($array)));
    • opción .8. $keys = array_keys($array); $x = $array[$keys[count($keys)-1]];
  • estas opciones escalan mejor para matrices muy grandes
    • opción .5. $x = end($array); reset($array);
    • opción .7. $x = $array[count($array)-1];
    • opción .9. $x = $array[] = array_pop($array);
    • opción 10. $x = $array[array_key_last($array)]; (desde PHP 7.3)
  • estas opciones solo deben usarse para arreglos indexados automáticamente :
    • opción .7. $x = $array[count($array)-1];(debido al uso decount)
    • opción .9. $x = $array[] = array_pop($array);(debido a que el valor asignado pierde la clave original)
  • esta opción no conserva el puntero interno de la matriz
    • opción .5. $x = end($array); reset($array);
  • Esta opción es un intento de modificar la opción .5. para preservar el puntero interno de la matriz (pero lamentablemente no se escala bien para matrices muy grandes)
    • opción .6. $x = end((array_values($array)));
  • la nueva array_key_lastfunción parece no tener ninguna de las limitaciones mencionadas anteriormente, con la excepción de que todavía es un RC en el momento de escribir este artículo (así que use el RC o espere su lanzamiento en diciembre de 2018):
    • opción 10. $x = $array[array_key_last($array)]; (desde PHP 7.3)

Un poco, dependiendo de si usa la matriz como pila o como cola , puede hacer variaciones en la opción 9.

Paul van Leeuwen
fuente
Si encuentra que falta una opción en particular, puede probarla usted mismo copiando y pegando juntos los fragmentos de código anteriores, comparándolo con una opción previamente probada. Agregar una opción a esta lista sería volver a probar todas las combinaciones para obtener resultados de rendimiento comparables. Si tiene una opción en particular que cree que debería agregarse, deje caer un comentario, tengo la intención de agregarla luego (aunque puede llevar algún tiempo).
Paul van Leeuwen
1
Muy buena respuesta, sin embargo, un comentario: para las matrices asociativas, la opción 9 no se puede usar también, porque estamos asignando de nuevo a una clave indexada automáticamente en lugar del nombre de la clave anterior.
Gras Double
1
Bonito resumen! Agregue mi respuesta usando el nuevo PHP 7.3. funcionar $array[array_key_last($array)];a su punto de referencia. Y por favor dame una notificación cuando hayas terminado. Me gustaría ver los resultados de rendimiento en comparación.
Clon de Quasimodo
2
@sz se produjo principalmente con mucha terquedad y paciencia, pero la selección general y las funciones de edición de varias líneas del editor de texto Sublime ayudaron. la regeneración tardó casi un día, por lo que si necesito hacerlo nuevamente, probablemente escribiré algo que convierta la salida de las 210 ejecuciones de acopladores en una tabla automáticamente :-)
Paul van Leeuwen
1
@ quasimodos-clone Regenere toda la tabla basada en el último PHP 5, 7 y su RC. Supongo que querremos generarlo nuevamente en diciembre cuando se publique. Gracias por traer esta nueva función a la atención de todos.
Paul van Leeuwen
487

Tratar

$myLastElement = end($yourArray);

Para restablecerlo (gracias @hopeseekr):

 reset($yourArray);

Enlace al manual

@David Murdoch agregó: $myLastElement = end(array_values($yourArray));// and now you don't need to call reset(). en E_STRICT esto produce la advertencia

Strict Standards: Only variables should be passed by reference

Gracias o_O Tync y todos!

Iznogood
fuente
38
Use $myLastElement = end(array_values($yourArray));y ahora no necesita llamar reset().
David Murdoch
55
@DavidMurdoch Quizás, pero seguro que agita la RAM y la CPU, creando la matriz temporal para los valores de la matriz ...
Theodore R. Smith
12
Si su servidor consume demasiada RAM, por lo que llamar a una función adicional simple es un factor decisivo, le sugiero que vuelva a examinar la configuración y los recursos de su servidor.
Chris Baker
3
end(array_values())dará un E_STRICT: "Solo las variables deben pasarse por referencia"
kolypto
32
Agregue paréntesis adicionales para evitar la advertencia estricta:end((array_values($yourArray)))
Daniel W.
212

Corto y dulce.

Se me ocurrió una solución para eliminar el mensaje de error y preservar la forma única y el rendimiento eficiente:

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

- solución previa

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

Nota: Los paréntesis adicionales son necesarios para evitar a PHP Strict standards: Only variables should be passed by reference.

rolacja
fuente
31
¡Después de exactamente 5 años, 6 meses y 2 días, ha enviado una respuesta más superior! ¡Gracias! y gracias Stack Overflow !!
Theodore R. Smith
1
Salude la respuesta, pero agregar los paréntesis adicionales se siente un poco hackisch. También phpStorm marcará esto como un error. Información adicional para agregar paréntesis adicionales ( phpsadness.com/sad/51 ). Para superar el error, podría convertirlo en un '2-liner': $array = array_slice($array, -1); $lastEl = array_pop($array);personalmente creo que esto es mejor (sin el 'error' del analizador)
Maurice
3
Puede usar la desreferenciación de esta manera: array_slice ($ array, -1) [0]
Vikash el
1
No puede si tiene cadenas como índice en la matriz
rolacja
3
Esta respuesta todavía necesita al menos dos comprobaciones para evitar avisos de PHP. 1. compruebe si array_size() > 1 2. Compruebe si la matriz es realmente una matriz. Todavía sigo con la respuesta de @Iznogood ya que la end()función incorporada de PHP ya hace todo el trabajo duro de una manera más eficiente.
Ema4rl
37

¿Qué tiene de malo array_slice($array, -1)? (Ver Manual: http://us1.php.net/array_slice )

array_slice()devuelve una matriz Probablemente no sea lo que estás buscando. Tú quieres el elemento.

Stoutie
fuente
21
Use array_slice($array, -1)[0]para obtener el elemento.
Pang
2
Esta es la respuesta. "fin" ¿Cambiar el puntero interno de la matriz? Pidiendo problemas, y muy difícil de leer!
Gerard ONeill
Me encanta este enfoque, aunque como señala @Pang, no está del todo completo. reset(array_slice($array, -1))es otro enfoque (que no causará un error si array_slice()devuelve algo "más pequeño" que una matriz de un solo elemento)
rinogo
El mejor enfoque, ya que puede modificar directamente el elemento:array_slice($array, -1)[0] = "";
HAlex
20

Una forma de evitar errores de paso por referencia (por ejemplo, "end (array_values ​​($ foo))" ") es usar 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))));
Warbo
fuente
Gran enfoque! (inserte el estándar 'Esta debería ser la respuesta aceptada' aquí)
Error
3
O simplemente agregue una parálisis adicional. Más corto y más dulce:end((array_values($yourArray)))
Dzhuneyt
44
El truco extra entre paréntesis se basa en un error en PHP, y ese enfoque ya no funciona en versiones posteriores de PHP (o al menos, no en PHP 7).
Matt Browne
1
Y el call_user_functruco tampoco funciona en PHP 7. Creo que estás atrapado con la creación de una variable temporal.
Matt Browne
15

Si no le importa modificar el puntero interno (admite matrices indexadas y asociativas):

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

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


Si desea una función de utilidad que no modifique el puntero interno (porque la matriz se pasa por valor y la función opera en una copia de ella):

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

Tenga en cuenta que PHP produce copias "sobre la marcha", es decir, solo cuando es realmente necesario. El end()mismo modifica la matriz, por lo que internamente se genera una copia de la matriz.


Por lo tanto, la siguiente alternativa es realmente más rápida ya que internamente no copia la matriz, solo hace un corte:

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

Este "foreach / return" es un ajuste para obtener de manera eficiente el primer elemento (y aquí solo).


Finalmente, la alternativa más rápida pero solo para matrices indexadas:

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



Para el registro, aquí hay otra respuesta mía , para el primer elemento de la matriz.

Gras Double
fuente
Usted proporciona 2 implementaciones alternativas para una array_lastfunción. Para el primero, indica que $arrayse copia y para el segundo que no se copia. ¿Dónde está la diferencia / por qué se copia en la primera implementación y no en la segunda?
Paul van Leeuwen
1
@PaulvanLeeuwen Comprendí por qué te confundiste. Traté de aclarar la respuesta , ¿es mejor?
Gras Double
10

no probado: ¿no funcionaría esto?

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

Dado que la matriz devuelta por array_values ​​es fugaz, a nadie le importa si se restablece su puntero.

y si necesitas la clave para ir, supongo que lo harías:

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

Necesito esto con bastante frecuencia para lidiar con las pilas, y siempre me encuentro desconcertado de que no haya una función nativa que lo haga sin manipular la matriz o su puntero interno de alguna forma.

Por lo tanto, generalmente llevo una función util que también es segura de usar en matrices asociativas.

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

    $keys = array_keys($array);
    return $array[$keys[sizeof($keys) - 1]];
}
Thrau
fuente
1
Buenas noticias, lo están convirtiendo en una función nativa :-) Puede ver su planificación de lanzamiento aquí: wiki.php.net/todo/php73 (se espera el 13 de diciembre de 2018 en el momento de escribir este artículo).
Paul van Leeuwen
9

Para obtener el último elemento de una matriz, use:

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

Punto de referencia

Repetí 1,000 veces, agarrando el último elemento de arreglos pequeños y grandes que contenían 100 y 50,000 elementos, respectivamente.

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...

Usé PHP versión 5.5.32.

Westy92
fuente
¿Qué pasa con el uso de $ array [array_keys ($ array) [count (array_keys ($ array)) - 1]]?
user2782001
hmm..array_keys parece escalar bastante mal.
user2782001
1
En realidad, es una locura más rápida que la matriz grande (0.0002) muestre el elemento y lo vuelva a poner ... $ val = $ ar [] = $ array_pop ($ ar);
user2782001
1
@ Westy92 Sus unidades parecen equivocadas en el punto de referencia. El número más pequeño que da es 0.00031 ... microsegundos, que es aproximadamente 0.3 nanosegundos. Eso significaría que su prueba tomó un reloj para ejecutarse si tiene una computadora nueva. Supongo que querías decir milisegundos o incluso segundos .
cesoide
1
Los valores son claramente varios órdenes de magnitud incorrectos. ¿Por qué centrarse en el rendimiento de todos modos?
istepaniuk
6

end () proporcionará el último elemento de una matriz

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

$array1 = array('a', 'b', 'c', 'd');
echo end($array1); //output: d
Ajith
fuente
1
Esta solución funciona, pero cambia el puntero interno de la matriz, no creo que sea la forma correcta.
UnixAgain
5

A partir de la versión 7.3 de PHP, se han introducido las funciones array_key_firsty array_key_last.

Dado que las matrices en PHP no son tipos de matriz estrictos, es decir, colecciones de tamaño fijo de campos de tamaño fijo que comienzan en el índice 0, sino una matriz asociativa extendida dinámicamente, el manejo de posiciones con claves desconocidas es difícil y las soluciones alternativas no funcionan muy bien. Por el contrario, las matrices reales se abordarían internamente a través de la aritmética del puntero muy rápidamente y el último índice ya se conoce en tiempo de compilación por declaración.

Al menos el problema con la primera y la última posición se resuelve con funciones incorporadas ahora desde la versión 7.3. Esto incluso funciona sin ninguna advertencia en los literales de matriz listos para usar :

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

Obviamente el último valor es:

$array[array_key_last($array)];
El clon de cuasimodo
fuente
1
Gracias por señalar esto a todos. Para aquellos que están ansiosos por usar esto: por favor, no es que este es un RC en el momento de escribir este artículo. Su lanzamiento está programado para diciembre de 2018.
Paul van Leeuwen
1
Esta es una gran noticia. Acabo de publicar un polyfill / shim en mi respuesta a continuación para que la gente pueda comenzar a usar esta sintaxis de inmediato.
Mark Thomson
3
$lastValue = end(array_values($array))

No se realiza ninguna modificación en los punteros de $ array. Esto evita el

reset($array)

que puede no ser deseado en ciertas condiciones.

Vihaan Verma
fuente
3

Para mi:

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

Con asociados:

$last =array_values($array)[count($array - 1)]
Mirko Pagliai
fuente
Proporcione algún contexto a su respuesta.
Shawn
2
@Shawn ¿Qué contexto? No necesito contexto. Código agregado para matrices asociativas.
Mirko Pagliai
3

Las respuestas principales son geniales, pero como lo mencionaron @ paul-van-leeuwen y @ quasimodos-clone, PHP 7.3 introducirá dos nuevas funciones para resolver este problema directamente: array_key_first () y array_key_last () .

Puede comenzar a usar esta sintaxis hoy con las siguientes funciones de 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)];

Advertencia: Esto requiere PHP 5.4 o superior.

Mark Thomson
fuente
2

Para hacer esto y evitar el E_STRICT y no meterse con el puntero interno de la matriz, puede usar:

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

$last_element = lelement($array);

lelement solo funciona con una copia, por lo que no afecta el puntero de la matriz.

Damiene
fuente
2

Otra solución:

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

Una posible solución más ...

$last_element = array_reverse( $array )[0];
Charles Garrison
fuente
No trabajar en matrices asociativas no parece una razón suficiente para rechazarme. En cuanto a la calidad, esta respuesta no es peor que muchas otras respuestas a esta pregunta. No entiendo por qué veo al menos 2 votos negativos en este momento. (puntuación de -2). De todos modos, vota a favor para mí, no es tan malo.
Paul van Leeuwen
2

Qué tal si:

current(array_slice($array, -1))
  • funciona para matrices asociativas
  • funciona cuando $array == [](regresa false)
  • no afecta la matriz original
Bouke Versteegh
fuente
2

Obtendrá el último elemento de una matriz fácilmente utilizando la lógica a continuación

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

No solo el último elemento, sino que también puede obtener el segundo último, el último último, etc., utilizando la lógica a continuación.

para el segundo último elemento, debe pasar solo el número 2 en la declaración anterior, por ejemplo:
echo ($ array [count ($ array) -2]);

Amzad Khan
fuente
1

Para obtener el último valor de Array:

array_slice($arr,-1,1) ;

Para eliminar la matriz de formulario de último valor:

array_slice($arr,0,count($arr)-1) ;
Rishabh
fuente
1
array_slice($arr,-1,1)dará como resultado otra matriz con longitud 1, no el último elemento
Vic
Tomemos un ejemplo: $a=array("red","green","blue","yellow","brown"); print_r(array_slice($a,-1,1)); Resultado:Array ( [0] => brown )
Rishabh
1

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

No restablece la matriz y no da advertencias ESTRICTAS.

PD. Como la respuesta más votada todavía no tiene el paréntesis doble, presenté esta respuesta.

Daan
fuente
1

Creo que esta es una ligera mejora en todas las respuestas existentes:

$lastElement = count($array) > 0 ? array_values(array_slice($array, -1))[0] : null;
  • Funciona mejor que end()o con soluciones array_keys(), especialmente con matrices grandes
  • No modificará el puntero interno de la matriz
  • No intentará acceder a un desplazamiento indefinido para matrices vacías
  • Funcionará como se espera para matrices vacías, matrices indexadas, matrices mixtas y matrices asociativas.
Adelmar
fuente
Lamentablemente, no funciona con matrices asociativas, porque el elemento único de la porción puede tener una clave con nombre.
Gras Double
Tienes razón, editado para agregar una solución ( array_valuesen el segmento de un solo elemento)
Adelmar
1

Use la función end ().

$array = [1,2,3,4,5];
$last = end($array); // 5
Brian Berneker
fuente
1
Solo preste atención a que esta función mueve el puntero de su matriz a esa posición.
giovannipds
También tenga en cuenta que esto se publicó como respuesta 8 años antes. stackoverflow.com/a/3687368/1255289
miken32
1

Hoy en día, preferiría tener siempre este ayudante, como se sugiere en una respuesta php.net/end .

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

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

Esto siempre mantendrá el puntero como está y nunca tendremos que preocuparnos por paréntesis, estándares estrictos o lo que sea.

giovannipds
fuente
Ya mencionado anteriormente: stackoverflow.com/a/45333947/1255289
miken32
0

Nota: Para (PHP 7> = 7.3.0) podemos usar array_key_last - Obtiene la última clave de una matriz

array_key_last ( array $array ) : mixed

Ref: http://php.net/manual/en/function.array-key-last.php

lokender singh
fuente
1
Esto ya estaba cubierto en muchas otras respuestas.
miken32
pero respondí antes que otros
lokender singh
-1

¿Qué sucede si desea obtener el último elemento de la matriz dentro del bucle de su matriz?

El siguiente código dará como resultado un bucle infinito:

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

La solución es obviamente simple para matrices no asociativas:

$last_element = $array[sizeof ($array) - 1];
foreach ($array as $key => $item) {
 if ($last_element == $item) {
   // something useful here
 }
}
Vadim Podlevsky
fuente
2
Sé sobre las funciones end () y reset (). Mi comentario estaba relacionado con bucles como foreach o while donde no puede usar estas funciones porque la función reset restablece el puntero interno de una matriz que se usa en el bucle para la iteración. Lo siento, la pregunta era más simple, solo quería dar una situación más avanzada que encontré en mi proyecto. Atentamente.
Vadim Podlevsky
Esto está mal en muchos sentidos (matrices con duplicados, comparación no estricta ...) y, en cualquier caso, no está realmente relacionado con la pregunta.
Tgr
use la función end ($ array) para obtener el último elemento, ¿por qué usa bucles innecesariamente?
Mahak Choudhary
1
@MahakChoudhary Mi comentario es una adición a "cómo obtener el último elemento de la matriz si ya está haciendo algunas manipulaciones dentro de un bucle de esta matriz. El uso de end () restablecerá el puntero innver y romperá el bucle de iteración. ¡Salud!
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;
}
Hussy Borad
fuente
-1

A partir de PHP 7.3, array_key_lastestá disponible

$lastEl = $myArray[array_key_last($myArray)];
Tagarikdi Djakouba
fuente
Esto ya se ha mencionado en muchas otras respuestas.
miken32
-1

Muy simple

$array = array('a', 'b', 'c', 'd');
end($array)
Jasmeen Maradeeya
fuente
Es de mencionar que esto tiene un comportamiento extraño si usa matrices con huecos. es decir $a = array(); $a[2] = 'c'; $a[1] = 'b'; echo end($a); , volveráb
Simon Zyx
Esto ya se publicó hace 9 años. stackoverflow.com/a/3687368/1255289
miken32