Comprobación durante la iteración de la matriz, si el elemento actual es el último elemento


78

Ayúdame a traducir este pseudocódigo a código php real:

 foreach ($arr as $k => $v)
    if ( THIS IS NOT THE LAST ELEMENT IN THE ARRAY)
        doSomething();

Editar: la matriz puede tener claves numéricas o de cadena


6
¿Por qué no usar forbucle para count($arr) - 1iteraciones?
— Marcin

1
Si tiene claves mixtas, ¿cómo se determina qué clave es el último elemento? Si lo desea como el último elemento agregado a la matriz, entonces debe haber algunos datos para indicar una marca de tiempo.
— Rasika

definición de último: por el orden interno de la matriz. Lo que es idéntico a decir el último elemento que seleccionará el bucle foreach
— shealtiel

Respuestas:


140

puedes usar end () de PHP

$array = array('a' => 1,'b' => 2,'c' => 3);
$lastElement = end($array);
foreach($array as $k => $v) {
    echo $v . '<br/>';
    if($v == $lastElement) {
         // 'you can do something here as this condition states it just entered last element of an array'; 
    }
}

Actualización1

como lo señaló @Mijoja, lo anterior podría tener problemas si tiene el mismo valor varias veces en la matriz. a continuación se muestra la solución.

$array = array('a' => 1, 'b' => 2, 'c' => 3, 'd' => 2);
//point to end of the array
end($array);
//fetch key of the last element of the array.
$lastElementKey = key($array);
//iterate the array
foreach($array as $k => $v) {
    if($k == $lastElementKey) {
        //during array iteration this condition states the last element.
    }
}

Actualización2

Encontré que la solución de @onteria_ es mejor que lo que respondí, ya que no modifica el puntero interno de las matrices, estoy actualizando la respuesta para que coincida con su respuesta.

$array = array('a' => 1, 'b' => 2, 'c' => 3, 'd' => 2);
// Get array keys
$arrayKeys = array_keys($array);
// Fetch last array key
$lastArrayKey = array_pop($arrayKeys);
//iterate array
foreach($array as $k => $v) {
    if($k == $lastArrayKey) {
        //during array iteration this condition states the last element.
    }
}

Gracias @onteria_

Actualización3

Como señaló @CGundlach, se introdujo PHP 7.3, array_key_lastque parece una opción mucho mejor si está utilizando PHP> = 7.3

$array = array('a' => 1,'b' => 2,'c' => 3);
$lastKey = array_key_last($array);
foreach($array as $k => $v) {
    echo $v . '<br/>';
    if($k == $lastKey) {
         // 'you can do something here as this condition states it just entered last element of an array'; 
    }
}

11
Esto tendrá problemas si tiene el mismo valor varias veces en la matriz
— Mijoja

1
@IbrahimAzharArmar Acabo de encontrar esta respuesta y mientras implementaba su solución noté que desde PHP 7.3 ahora existe la función array_key_last, que también devuelve la última clave de una matriz sin afectar el puntero interno: secure.php.net/array_key_last . Simplificaría su solución aún más :)
— CGundlach

1
@CGundlach, es bueno saberlo. Actualizará la respuesta. Gracias.
— Ibrahim Azhar Armar

26

Esto siempre me funciona

foreach($array as $key => $value) {
   if (end(array_keys($array)) == $key)
       // Last key reached
}

Editar 30/04/15

$last_key = end(array_keys($array));
reset($array);

foreach($array as $key => $value) {
  if ( $key == $last_key)
      // Last key reached
}

Para evitar la advertencia E_STRICT mencionada por @Warren Sergent

$array_keys = array_keys($array);
$last_key = end($array_keys);

mucho más elegante y fácil! :)
— Rafael Moni

No estoy seguro de por qué este comentario no es la respuesta aceptada. Es de lejos la más simple / limpia de todas las respuestas proporcionadas y funciona para la gran mayoría de casos de uso potenciales (es decir, matrices asociativas y enumeradas).
— Pierce

1
@Pierce para darle una pista: esto fue respondido 3 años y medio después de la respuesta aceptada, además, si tiene 1000 elementos en su matriz, llamará "end" 1000 veces y "array_keys" 1000 veces.
— StefanNch

Esto claramente tiene problemas de rendimiento si está iterando sobre una matriz grande. Mi sugerencia en ese caso es mover el final (array_keys ($ array)) fuera del ciclo. Pero asegúrese de restablecer la matriz antes de la iteración.
— Richard Merchant

Si quieres ser pedante, en modo estricto, end (array_keys ($ array)) generará un aviso, ya que "Solo las variables deben pasarse por referencia" - para corregir esto, defina $ array_keys = array_keys ($ array) y llame end () en la variable $ array_keys.
— Warren Sergent

14
$myarray = array(
  'test1' => 'foo',
  'test2' => 'bar',
  'test3' => 'baz',
  'test4' => 'waldo'
);

$myarray2 = array(
'foo',
'bar',
'baz',
'waldo'
);

// Get the last array_key
$last = array_pop(array_keys($myarray));
foreach($myarray as $key => $value) {
  if($key != $last) {
    echo "$key -> $value\n";
  }
}

// Get the last array_key
$last = array_pop(array_keys($myarray2));
foreach($myarray2 as $key => $value) {
  if($key != $last) {
    echo "$key -> $value\n";
  }
}

Dado que array_popfunciona en la matriz temporal creada por array_keys, no modifica la matriz original en absoluto.

$ php test.php
test1 -> foo
test2 -> bar
test3 -> baz
0 -> foo
1 -> bar
2 -> baz

Me gusta esto más que la respuesta aceptada porque solo requiere una línea para la inicialización fuera del ciclo.
— Jordan Lev

Me gusta esto más que la respuesta aceptada porque no altera el puntero interno de la matriz que está a punto de recorrer.
— Autónomo

hacer lo mismo para el primer elemento$first = array_shift(array_keys($myarray2));
— Lucas

2
Esto produce un aviso en E_STRICT: Aviso de tiempo de ejecución: solo las variables deben pasar por referencia
— Vigintas Labakojis

Este parece un mejor enfoque que mi respuesta, actualizando mi respuesta.
— Ibrahim Azhar Armar

6

Por qué no este método tan simple:

$i = 0; //a counter to track which element we are at
foreach($array as $index => $value) {
    $i++;
    if( $i == sizeof($array) ){
        //we are at the last element of the array
    }
}

2

Sé que esto es antiguo, y usar el iterador SPL tal vez sea una exageración, pero de todos modos, otra solución aquí:

$ary = array(1, 2, 3, 4, 'last');
$ary = new ArrayIterator($ary);
$ary = new CachingIterator($ary);
foreach ($ary as $each) {
    if (!$ary->hasNext()) { // we chain ArrayIterator and CachingIterator
                            // just to use this `hasNext()` method to see
                            // if this is the last element
       echo $each;
    }
}

1

Mi solución, también bastante simple ..

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

foreach($array as $index => $value) 
{
     if($index == $last)
        // this is last array
     else
        // this is not last array
}

Esto es bastante agradable y simple, siempre que sus claves de matriz se hayan generado automáticamente.
— Matt Kieran

0

Si los elementos están ordenados numéricamente, utilice la función key () para determinar el índice del elemento actual y compararlo con la longitud. Tendría que usar next () o prev () para recorrer los elementos en un ciclo while en lugar de un ciclo for:

$length = sizeOf($arr);
while (key(current($arr)) != $length-1) {
    $v = current($arr); doSomething($v); //do something if not the last item
    next($myArray); //set pointer to next item
}

Porque es lo primero que encontré cuando busqué en Google. Es bueno conocer todas las diferentes formas de hacer lo mismo y estar mejor versado. : D
— trusktr

1
No funcionará para artículos que no sean numéricos o que no estén estrictamente ordenados
— shealtiel

0
$arr = array(1, 'a', 3, 4 => 1, 'b' => 1);
foreach ($arr as $key => $val) {
    echo "{$key} = {$val}" . (end(array_keys($arr))===$key ? '' : ', ');
}
// output: 0 = 1, 1 = a, 2 = 3, 4 = 1, b = 1
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.