Antworten:
Sie könnten einen Zähler verwenden:
$i = 0;
$len = count($array);
foreach ($array as $item) {
if ($i == 0) {
// first
} else if ($i == $len - 1) {
// last
}
// …
$i++;
}
$i = 1
, müssen Sie sich keine Sorgen machen $len - 1
, verwenden Sie einfach $len
.
Wenn Sie eine Lösung bevorzugen, bei der der Zähler außerhalb der Schleife nicht initialisiert werden muss, schlage ich vor, den aktuellen Iterationsschlüssel mit der Funktion zu vergleichen, die Ihnen den letzten / ersten Schlüssel des Arrays angibt.
Dies wird mit dem kommenden PHP 7.3 etwas effizienter (und lesbarer).
foreach($array as $key => $element) {
if ($key === array_key_first($array))
echo 'FIRST ELEMENT!';
if ($key === array_key_last($array))
echo 'LAST ELEMENT!';
}
foreach($array as $key => $element) {
reset($array);
if ($key === key($array))
echo 'FIRST ELEMENT!';
end($array);
if ($key === key($array))
echo 'LAST ELEMENT!';
}
end()
+ key()
über jede Iteration der Schleife - wenn es beides ist, werden jedes Mal 4 Methoden aufgerufen. Zugegeben, das wären sehr einfache Operationen und wahrscheinlich nur Zeigersuchen, aber dann geben die Dokumente dies an reset()
und end()
ändern den internen Zeiger des Arrays - ist es also schneller als ein Zähler? möglicherweise nicht.
reset()
Anruf vor dem foreach verschieben und das Ergebnis zwischenspeichern $first
.
Um den letzten Artikel zu finden, funktioniert dieser Code jedes Mal:
foreach( $items as $item ) {
if( !next( $items ) ) {
echo 'Last Item';
}
}
[true,true,false,true]
. Aber ich persönlich werde dies immer dann verwenden, wenn ich es mit einem Array zu tun habe, das keinen Booleschen Wert enthält false
.
next()
sollte NIEMALS in einer foreach-Schleife verwendet werden. Es bringt den internen Array-Zeiger durcheinander. Weitere Informationen finden Sie in der Dokumentation.
Eine vereinfachte Version des oben genannten und vorausgesetzt, Sie verwenden keine benutzerdefinierten Indizes ...
$len = count($array);
foreach ($array as $index => $item) {
if ($index == 0) {
// first
} else if ($index == $len - 1) {
// last
}
}
Version 2 - Weil ich gekommen bin, um das else zu verabscheuen, es sei denn, es ist notwendig.
$len = count($array);
foreach ($array as $index => $item) {
if ($index == 0) {
// first
// do something
continue;
}
if ($index == $len - 1) {
// last
// do something
continue;
}
}
if ($index == count($array) - 1)
. Siehe hier .
Sie können das erste und das letzte Element aus dem Array entfernen und separat verarbeiten.
So was:
<?php
$array = something();
$first = array_shift($array);
$last = array_pop($array);
// do something with $first
foreach ($array as $item) {
// do something with $item
}
// do something with $last
?>
Das Entfernen aller Formatierungen in CSS anstelle von Inline-Tags würde Ihren Code verbessern und die Ladezeit verkürzen.
Sie können auch vermeiden, HTML mit PHP-Logik zu mischen, wann immer dies möglich ist.
Ihre Seite könnte viel lesbarer und wartbarer werden, indem Sie folgende Dinge trennen:
<?php
function create_menu($params) {
//retrieve menu items
//get collection
$collection = get('xxcollection') ;
foreach($collection as $c) show_collection($c);
}
function show_subcat($val) {
?>
<div class="sub_node" style="display:none">
<img src="../images/dtree/join.gif" align="absmiddle" style="padding-left:2px;" />
<a id="'.$val['xsubcatid'].'" href="javascript:void(0)" onclick="getProduct(this , event)" class="sub_node_links" >
<?php echo $val['xsubcatname']; ?>
</a>
</div>
<?php
}
function show_cat($item) {
?>
<div class="node" >
<img src="../images/dtree/plus.gif" align="absmiddle" class="node_item" id="plus" />
<img src="../images/dtree/folder.gif" align="absmiddle" id="folder">
<?php echo $item['xcatname']; ?>
<?php
$subcat = get_where('xxsubcategory' , array('xcatid'=>$item['xcatid'])) ;
foreach($subcat as $val) show_subcat($val);
?>
</div>
<?php
}
function show_collection($c) {
?>
<div class="parent" style="direction:rtl">
<img src="../images/dtree/minus.gif" align="absmiddle" class="parent_item" id="minus" />
<img src="../images/dtree/base.gif" align="absmiddle" id="base">
<?php echo $c['xcollectionname']; ?>
<?php
//get categories
$cat = get_where('xxcategory' , array('xcollectionid'=>$c['xcollectionid']));
foreach($cat as $item) show_cat($item);
?>
</div>
<?php
}
?>
Ein Versuch, den ersten zu finden, wäre:
$first = true;
foreach ( $obj as $value )
{
if ( $first )
{
// do something
$first = false; //in order not to get into the if statement for the next loops
}
else
{
// do something else for all loops except the first
}
}
Einfach das funktioniert!
// Set the array pointer to the last key
end($array);
// Store the last key
$lastkey = key($array);
foreach($array as $key => $element) {
....do array stuff
if ($lastkey === key($array))
echo 'THE LAST ELEMENT! '.$array[$lastkey];
}
Vielen Dank für Ihre @billynoah das Aussortieren Ende Problem.
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()
bekommt eine ganze Zahl, nicht end()
. end()
" gibt den Wert des letzten Elements zurück " und key()
erwartet ein Array als Eingabe.
1: Warum nicht eine einfache for
Aussage verwenden? Angenommen, Sie verwenden ein reales Array und kein Array, können Iterator
Sie leicht überprüfen, ob die Zählervariable 0 oder eins weniger als die Gesamtzahl der Elemente ist. Meiner Meinung nach ist dies die sauberste und verständlichste Lösung ...
$array = array( ... );
$count = count( $array );
for ( $i = 0; $i < $count; $i++ )
{
$current = $array[ $i ];
if ( $i == 0 )
{
// process first element
}
if ( $i == $count - 1 )
{
// process last element
}
}
2: Sie sollten in Betracht ziehen, verschachtelte Mengen zum Speichern Ihrer Baumstruktur zu verwenden. Zusätzlich können Sie das Ganze durch rekursive Funktionen verbessern.
for
möchten, können Sie eine Schleife von 1
bis ausführen n-1
und das if
s aus dem Körper entfernen. Es macht keinen Sinn, sie wiederholt zu überprüfen.
Beste Antwort:
$arr = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
foreach ($arr as $a) {
// This is the line that does the checking
if (!each($arr)) echo "End!\n";
echo $a."\n";
}
Die effizienteste Antwort von @morg funktioniert im Gegensatz dazu foreach
nur für richtige Arrays, nicht für Hash-Map-Objekte. Diese Antwort vermeidet den Overhead einer bedingten Anweisung für jede Iteration der Schleife, wie in den meisten dieser Antworten (einschließlich der akzeptierten Antwort), indem das erste und das letzte Element spezifisch behandelt und die mittleren Elemente durchlaufen werden.
Das array_keys
Funktion kann verwendet werden, damit die effiziente Antwort wie folgt funktioniert foreach
:
$keys = array_keys($arr);
$numItems = count($keys);
$i=0;
$firstItem=$arr[$keys[0]];
# Special handling of the first item goes here
$i++;
while($i<$numItems-1){
$item=$arr[$keys[$i]];
# Handling of regular items
$i++;
}
$lastItem=$arr[$keys[$i]];
# Special handling of the last item goes here
$i++;
Ich habe diesbezüglich kein Benchmarking durchgeführt, aber der Schleife wurde keine Logik hinzugefügt. Dies ist der größte Leistungseinbruch. Daher würde ich vermuten, dass die mit der effizienten Antwort gelieferten Benchmarks ziemlich nahe beieinander liegen.
Wenn Sie so etwas funktionalisieren wollten , habe ich hier eine solche iterateList-Funktion ausprobiert . Möglicherweise möchten Sie jedoch den Kerncode vergleichen, wenn Sie sich große Sorgen um die Effizienz machen. Ich bin mir nicht sicher, wie viel Overhead der gesamte Funktionsaufruf mit sich bringt.
Bei Skripten zur Generierung von SQL-Abfragen oder bei Skripten, die eine andere Aktion für das erste oder letzte Element ausführen, ist es viel schneller (fast doppelt so schnell), unnötige Variablenprüfungen zu vermeiden.
Die aktuell akzeptierte Lösung verwendet eine Schleife und eine Prüfung innerhalb der Schleife, die bei jeder einzelnen Wiederholung durchgeführt wird. Der richtige (schnelle) Weg, dies zu tun, ist der folgende:
$numItems = count($arr);
$i=0;
$firstitem=$arr[0];
$i++;
while($i<$numItems-1){
$some_item=$arr[$i];
$i++;
}
$last_item=$arr[$i];
$i++;
Ein kleiner hausgemachter Benchmark zeigte Folgendes:
test1: 100000 Läufe von Model Morg
Zeit: 1869.3430423737 Millisekunden
Test2: 100000 Modellläufe, wenn zuletzt
Zeit: 3235.6359958649 Millisekunden
Und so ist es ziemlich klar, dass der Scheck viel kostet, und natürlich wird es noch schlimmer, je mehr variable Schecks Sie hinzufügen;)
$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++;
wird ausgegeben:0: , 1: One, 2: ,
array()
wird erstellt, {'one':"1 1 1",0:"",1:"One",2:"",3:"",4:"Four"}
aber die leeren Elemente werden mit count ignoriert. Sie zählen die Anzahl der definierten "Dinge". BOUNTY SACRIFICE EINGEHEND! Diese Antwort verdient Kopfgeld, aber wenn @Morg. weg, es ist sinnlos. Ich würde einer Person Kopfgeld geben, die SO wahrscheinlich nicht mehr verwenden wird! Wenn er zurückkommt und seine Antwort verbessert, verdient er das Kopfgeld!
array_keys
Funktion abrufen , die Sie wie ein Array behandeln können . Siehe meine "verbesserte" Antwort .
$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'";
Mit Schlüsseln und Werten funktioniert dies auch:
foreach ($array as $key => $value) {
if ($value === end($array)) {
echo "LAST ELEMENT!";
}
}
Die Verwendung einer booleschen Variablen ist immer noch die zuverlässigste, selbst wenn Sie das erste Auftreten von a überprüfen möchten $value
(ich fand es in meiner Situation und in vielen Situationen nützlicher) , wie folgt:
$is_first = true;
foreach( $array as $value ) {
switch ( $value ) {
case 'match':
echo 'appeared';
if ( $is_first ) {
echo 'first appearance';
$is_first = false;
}
break;
}
}
if( !next( $array ) ) {
echo 'last value';
}
}
Wie wäre !next( $array )
es dann, den letzten zu finden, der $value
zurückkehrt, true
wenn es keinen next()
Wert zum Iterieren gibt.
Und ich bevorzuge es, eine for
Schleife zu verwenden , anstatt foreach
einen Zähler wie diesen zu verwenden:
$len = count( $array );
for ( $i = 0; $i < $len; $i++ ) {
$value = $array[$i];
if ($i === 0) {
// first
} elseif ( $i === $len - 1 ) {
// last
}
// …
$i++;
}
Ich bin auf diesen Thread gestoßen, als ich das gleiche Problem habe. Ich brauche nur das erste Element, dann analysiere ich meinen Code erneut, bis mir dies einfiel.
$firstElement = true;
foreach ($reportData->result() as $row)
{
if($firstElement) { echo "first element"; $firstElement=false; }
// Other lines of codes here
}
Die obigen Codes sind großartig und vollständig, aber wenn Sie nur das erste Element benötigen, können Sie diesen Code ausprobieren.
Ich bin mir nicht sicher, ob es noch notwendig ist. Die folgende Lösung sollte jedoch mit Iteratoren funktionieren und ist nicht erforderlich count
.
<?php
foreach_first_last(array(), function ($key, $value, $step, $first, $last) {
echo intval($first), ' ', intval($last), ' ', $step, ' ', $value, PHP_EOL;
});
foreach_first_last(array('aa'), function ($key, $value, $step, $first, $last) {
echo intval($first), ' ', intval($last), ' ', $step, ' ', $value, PHP_EOL;
});
echo PHP_EOL;
foreach_first_last(array('aa', 'bb', 'cc'), function ($key, $value, $step, $first, $last) {
echo intval($first), ' ', intval($last), ' ', $step, ' ', $value, PHP_EOL;
});
echo PHP_EOL;
function foreach_first_last($array, $cb)
{
$next = false;
$current = false;
reset($array);
for ($step = 0; true; ++$step) {
$current = $next;
$next = each($array);
$last = ($next === false || $next === null);
if ($step > 0) {
$first = $step == 1;
list ($key, $value) = $current;
if (call_user_func($cb, $key, $value, $step, $first, $last) === false) {
break;
}
}
if ($last) {
break;
}
}
}
Sie können auch eine anonyme Funktion verwenden:
$indexOfLastElement = count($array) - 1;
array_walk($array, function($element, $index) use ($indexOfLastElement) {
// do something
if (0 === $index) {
// first element‘s treatment
}
if ($indexOfLastElement === $index) {
// last not least
}
});
Drei weitere Dinge sollten erwähnt werden:
array_values
zuerst .$element
Sie es als Referenz übergeben (&$element
).$indexOfLastElement
dem use
Konstrukt aufgelistet werden, bei Bedarf erneut als Referenz.Sie können den Zähler und die Array-Länge verwenden.
$ array = array (1,2,3,4); $ i = 0; $ len = count ($ array); foreach ($ array als $ item) { if ($ i === 0) { // zuerst } else if ($ i === $ len - 1) { // letzte }} //… $ i ++; }}
foreach ($arquivos as $key => $item) {
reset($arquivos);
// FIRST AHEAD
if ($key === key($arquivos) || $key !== end(array_keys($arquivos)))
$pdf->cat(null, null, $key);
// LAST
if ($key === end(array_keys($arquivos))) {
$pdf->cat(null, null, $key)
->execute();
}
}
Verwenden von reset ($ array) und end ($ array)
<?php
$arrays = [1,2,3,4,5];
$first = reset($arrays);
$last = end($arrays);
foreach( $arrays as $array )
{
if ( $first == $array )
{
echo "<li>{$array} first</li>";
}
else if ( $last == $array )
{
echo "<li>{$array} last</li>";
}
else
{
echo "<li>{$array}</li>";
}
}
Versuche dies:
function children( &$parents, $parent, $selected ){
if ($parents[$parent]){
$list = '<ul>';
$counter = count($parents[$parent]);
$class = array('first');
foreach ($parents[$parent] as $child){
if ($child['id'] == $selected) $class[] = 'active';
if (!--$counter) $class[] = 'last';
$list .= '<li class="' . implode(' ', $class) . '"><div><a href="]?id=' . $child['id'] . '" alt="' . $child['name'] . '">' . $child['name'] . '</a></div></li>';
$class = array();
$list .= children($parents, $child['id'], $selected);
}
$list .= '</ul>';
return $list;
}
}
$output .= children( $parents, 0, $p_industry_id);
array_shift
undarray_pop
. Obwohl dies die Lösung ist, die ich gefunden hätte, wenn ich so etwas implementieren müsste, würde ich mich jetzt an die Antwort von Rok Kralj halten .