La pregunta es simple. Tengo un foreach
bucle en mi código:
foreach($array as $element) {
//code
}
En este ciclo, quiero reaccionar de manera diferente cuando estamos en la primera o la última iteración.
¿Como hacer esto?
Podrías usar un contador:
$i = 0;
$len = count($array);
foreach ($array as $item) {
if ($i == 0) {
// first
} else if ($i == $len - 1) {
// last
}
// …
$i++;
}
array_shift
yarray_pop
. Aunque esta es la solución que se me ocurrió si tuviera que implementar tal cosa, seguiría con la respuesta de Rok Kralj ahora.$i = 1
, no tiene que preocuparse$len - 1
, solo use$len
.Si prefiere una solución que no requiera la inicialización del contador fuera del ciclo, propongo comparar la clave de iteración actual con la función que le indica la última / primera clave de la matriz.
Esto se vuelve algo más eficiente (y más legible) con el próximo PHP 7.3.
Solución para PHP 7.3 y superior:
Solución para todas las versiones de PHP:
fuente
end()
+key()
en cada iteración del bucle; si son ambos, se llaman 4 métodos cada vez. De acuerdo, esas serían operaciones muy livianas y probablemente sean solo búsquedas de puntero, pero luego los documentos continúan especificando esoreset()
yend()
modificando el puntero interno de la matriz, entonces, ¿es más rápido que un contador? posiblemente no.reset()
llamada antes del foreach y guardar el resultado en caché$first
.Para encontrar el último elemento, encuentro que este código funciona cada vez:
fuente
next
: Advertencia Esta función puede devolver un valor booleanoFALSE
, pero también puede devolver un valor no booleano que se evalúa comoFALSE
. Lea la sección sobre booleanos para obtener más información. Use el===
operador para probar el valor de retorno de esta función.[true,true,false,true]
. Pero personalmente usaré esto cada vez que esté tratando con una matriz que no contiene booleanfalse
.next()
debe NUNCA ser utilizado dentro de un bucle foreach. Desordena el puntero interno de la matriz. Consulte la documentación para más información.Una versión más simplificada de lo anterior y suponiendo que no esté utilizando índices personalizados ...
Versión 2 - Porque he detestado usar el else a menos que sea necesario.
fuente
if ($index == count($array) - 1)
. Ver aquí .Puede eliminar el primer y el último elemento de la matriz y procesarlos por separado.
Me gusta esto:
Eliminar todo el formato a CSS en lugar de etiquetas en línea mejoraría su código y aceleraría el tiempo de carga.
También puede evitar mezclar HTML con lógica php siempre que sea posible.
Su página podría hacerse mucho más legible y mantenible separando cosas como esta:
fuente
Un intento de encontrar el primero sería:
fuente
Simplemente esto funciona!
Gracias @billynoah por resolver el problema final .
fuente
if ($key === $lastkey)
.if ($lastkey === $key)
?PHP Warning: key() expects parameter 1 to be array, integer given in php shell code on line 1
key()
está obteniendo un número entero, noend()
.end()
" devuelve el valor del último elemento " ykey()
espera una matriz como entrada.1: ¿Por qué no usar una
for
declaración simple ? Suponiendo que está utilizando una matriz real y no unaIterator
, puede verificar fácilmente si la variable del contador es 0 o uno menos que la cantidad total de elementos. En mi opinión, esta es la solución más limpia y comprensible ...2: debe considerar el uso de conjuntos anidados para almacenar su estructura de árbol. Además, puede mejorar todo mediante el uso de funciones recursivas.
fuente
for
, puedes desplazarte de un lado1
a otron-1
y sacar elif
s del cuerpo. No tiene sentido revisarlos repetidamente.La mejor respuesta:
fuente
La respuesta más eficiente de @morg, a diferencia
foreach
, solo funciona para matrices adecuadas, no para objetos de mapa hash. Esta respuesta evita la sobrecarga de una declaración condicional para cada iteración del bucle, como en la mayoría de estas respuestas (incluida la respuesta aceptada) al manejar específicamente el primer y último elemento, y recorrer los elementos intermedios.La
array_keys
función se puede utilizar para hacer que la respuesta eficiente funcione comoforeach
:No he hecho una evaluación comparativa de esto, pero no se ha agregado ninguna lógica al ciclo, que es donde se produce el mayor éxito en el rendimiento, por lo que sospecho que los puntos de referencia proporcionados con la respuesta eficiente están bastante cerca.
Si quisieras funcionalizar este tipo de cosas, he dado un giro en esa función iterateList aquí . Sin embargo, es posible que desee comparar el código esencial si está muy preocupado por la eficiencia. No estoy seguro de cuánto sobrecarga introduce toda la invocación de función.
fuente
Para los scripts de generación de consultas SQL, o cualquier cosa que realice una acción diferente para el primer o el último elemento, es mucho más rápido (casi el doble de rápido) evitar el uso de comprobaciones de variables innecesarias.
La solución actual aceptada utiliza un bucle y una verificación dentro del bucle que se realizará en cada_site_iteración, la forma correcta (rápida) de hacer esto es la siguiente:
Un pequeño punto de referencia casero mostró lo siguiente:
test1: 100000 ejecuciones del modelo morg
tiempo: 1869.3430423737 milisegundos
test2: 100000 ejecuciones de modelo si duran
tiempo: 3235.6359958649 milisegundos
Y, por lo tanto, está bastante claro que el cheque cuesta mucho y, por supuesto, empeora aún más a medida que agrega más cheques;)
fuente
$arr = array('one' => "1 1 1", 4 => 'Four', 1 => 'One'); $numItems = count($arr); $i=0; $firstitem=$arr[0]; echo $i . ': ' . $firstitem . ", "; $i++; while($i<$numItems-1){ $some_item=$arr[$i]; echo $i . ': ' . $some_item . ", "; $i++; } $last_item=$arr[$i]; echo $i . ': ' . $last_item . ", "; $i++;
saldrá:0: , 1: One, 2: ,
array()
hecho es{'one':"1 1 1",0:"",1:"One",2:"",3:"",4:"Four"}
pero los elementos vacíos se ignoran con el recuento, ¡estás contando el número de "cosas" definidas! ¡SACRIFICIO CON REGALO ENTRANTE! Esta respuesta merece recompensa, pero si @Morg. desaparecido, no tiene sentido. ¡Daría recompensas a una persona que probablemente no usará SO nuevamente! Si regresa y mejora su respuesta, ¡merece la recompensa!array_keys
función, que puede tratar como una matriz. Vea mi respuesta "mejorada" .$querySet = ""; foreach ($fieldSet as $key=>$value) { $value = $db->dbLink->quote($value); $querySet .= "$key = $value, "; } $querySet = substr_replace($querySet, "", -2); $queryString = "UPDATE users SET $querySet WHERE user_ID = '$user_ID'";
Con Keys and Values esto también funciona:
fuente
El uso de una variable booleana sigue siendo el más confiable, incluso si desea verificar la primera aparición de un
$value
(lo encontré más útil en mi situación y en muchas situaciones) , como este:Entonces, ¿qué tal
!next( $array )
encontrar el último$value
que devolverátrue
si no hay ningúnnext()
valor para iterar?Y prefiero usar un
for
bucle en lugar deforeach
usar un contador, como este:fuente
Encontré este hilo cuando tengo el mismo problema. Solo necesito obtener el primer elemento, luego vuelvo a analizar mi código hasta que se me ocurre.
Los códigos anteriores son geniales y completos, pero si solo necesita el primer elemento, puede probar este código.
fuente
No estoy seguro si aún es necesario. Pero la siguiente solución debería funcionar con iteradores y no requiere
count
.fuente
También puede usar una función anónima:
Se deben mencionar tres cosas más:
array_values
primero debe canalizarla .$element
, debe pasarlo por referencia (&$element
).$indexOfLastElement
interior de lause
construcción, nuevamente por referencia si es necesario.fuente
Puede usar el contador y la longitud de la matriz.
fuente
fuente
Utilizando reset ($ array) y end ($ array)
Demo repl.it
fuente
Prueba esto:
fuente