Відповіді:
Ви можете використовувати лічильник:
$i = 0;
$len = count($array);
foreach ($array as $item) {
if ($i == 0) {
// first
} else if ($i == $len - 1) {
// last
}
// …
$i++;
}
$i = 1
, вам не доведеться хвилюватися $len - 1
, просто використовуйте $len
.
Якщо ви віддаєте перевагу рішенню, яке не потребує ініціалізації лічильника поза циклом, пропоную порівняти поточний ключ ітерації з функцією, яка повідомляє вам останній / перший ключ масиву.
Це стає дещо ефективнішим (і читабельніше) з майбутнім PHP 7.3.
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()
над кожною ітерацією циклу - якщо це обидва, то кожен раз викликають 4 методи. Зрозуміло, це були б дуже легкі операції і, ймовірно, є лише пошуковими вказівниками, але потім документи продовжують вказувати це reset()
та end()
змінювати внутрішній покажчик масиву - так це швидше, ніж лічильник? можливо, ні.
reset()
виклик перед програмою foreach та кешувати результат $first
.
Щоб знайти останній елемент, я вважаю, що цей фрагмент коду працює щоразу:
foreach( $items as $item ) {
if( !next( $items ) ) {
echo 'Last Item';
}
}
[true,true,false,true]
. Але особисто я буду використовувати це в будь-який час, коли я маю справу з масивом, який не містить булевих false
.
next()
не повинні НІКОЛИ бути використані всередині циклу Еогеасп. Він псує внутрішній покажчик масиву. Перегляньте документацію для отримання додаткової інформації.
Більш спрощена версія вищезазначеного та припускаючи, що ви не використовуєте власні індекси ...
$len = count($array);
foreach ($array as $index => $item) {
if ($index == 0) {
// first
} else if ($index == $len - 1) {
// last
}
}
Версія 2 - Тому що я не люблю використовувати інше, якщо не потрібно.
$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)
. Дивіться тут .
Ви можете видалити перший і останній елементи з масиву та обробити їх окремо.
Подобається це:
<?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
?>
Видалення всього форматування до CSS замість вбудованих тегів покращить ваш код та прискорить час завантаження.
Ви також можете уникати змішування HTML з логікою php, коли це можливо.
Ваша сторінка може бути набагато зручнішою для читання та ремонтування, розділивши такі речі:
<?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
}
?>
Спробою знайти першу було б:
$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
}
}
Просто це працює!
// 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];
}
Дякую @billynoah за те, що ви розібрали кінцевий випуск.
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()
отримує ціле число, а не end()
. end()
" повертає значення останнього елемента " і key()
очікує масив як вхідний.
1: Чому б не використати просте for
твердження? Якщо припустити, що ви використовуєте реальний масив, а не Iterator
ви, ви можете легко перевірити, чи змінна лічильника на 0 або на одну менша, ніж на всю кількість елементів. На мою думку, це найбільш чисто і зрозуміле рішення ...
$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: Вам слід розглянути можливість використання вкладених наборів для зберігання вашої структури дерева. Крім того, ви можете покращити все, використовуючи рекурсивні функції.
for
ви можете перевести цикл з 1
на n-1
та вийняти if
s з тіла. Немає сенсу перевіряти їх повторно.
Найкраща відповідь:
$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";
}
Найбільш ефективна відповідь від @morg, на відміну від цього foreach
, працює лише для правильних масивів, а не об’єктів хеш-карти. Ця відповідь дозволяє уникнути накладних витрат на умовне твердження для кожної ітерації циклу, як у більшості цих відповідей (включаючи прийняту відповідь) конкретно обробляючи перший і останній елемент, і перебираючи петлі на середні елементи.
array_keys
Функція може бути використана для ефективної роботи відповіді , як 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++;
Я не робив тестування з цього приводу, але до циклу не додано жодної логіки, яка була найбільшим ударом для продуктивності, тому я б підозрював, що орієнтири, що надаються з ефективною відповіддю, досить близькі.
Якщо ви хотіли функціонувати подібну річ, я тут перейнявся такою функцією iterateList . Хоча, можливо, ви захочете порівняти код суті, якщо вас дуже турбує ефективність. Я не впевнений, скільки накладних витрат викликає все виклик функції.
Для створення SQL-запитів, що генерують скрипти, або будь-якого іншого, що робить різні дії для перших або останніх елементів, набагато швидше (майже вдвічі швидше) уникнути використання не потрібних перевірок змінних.
Поточне прийняте рішення використовує цикл і перевірку в циклі, які будуть зроблені every_single_iteration, правильний (швидкий) спосіб зробити це наступний:
$numItems = count($arr);
$i=0;
$firstitem=$arr[0];
$i++;
while($i<$numItems-1){
$some_item=$arr[$i];
$i++;
}
$last_item=$arr[$i];
$i++;
Невеликий домашній тест показав наступне:
test1: 100000 пробіжок модельного моргу
час: 1869,3430423737 мілісекунд
test2: 100000 запусків моделі, якщо остання
час: 3235.6359958649 мілісекунд
І тому цілком зрозуміло, що чек коштує чимало, і, звичайно, стає ще гірше, чим більше змінних чеків, які ви додаєте;)
$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++;
вийде:0: , 1: One, 2: ,
array()
зроблений "Об'єкт" , {'one':"1 1 1",0:"",1:"One",2:"",3:"",4:"Four"}
але порожні елементи ігноруються підрахунком, ви рахуєте кількість визначених "речей" !! СВЯТИ СВЯТИ БУНТИ! Ця відповідь заслуговує на винагороду, але якщо @Morg. пішли, це безглуздо. Я б подарував щедрість людині, яка, ймовірно, не буде використовувати SO знову! Якщо він повернеться і вдосконалює свою відповідь, він заслуговує на винагороду!
array_keys
функції, яку ви можете розглядати як масив. Дивіться мою "покращену" відповідь .
$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'";
З ключами та значеннями це також працює:
foreach ($array as $key => $value) {
if ($value === end($array)) {
echo "LAST ELEMENT!";
}
}
Використання булевої змінної все ще є найбільш надійним, навіть якщо ви хочете перевірити першу появу $value
(я вважав, що це корисніше в моїй ситуації та в багатьох ситуаціях) , таких як ця:
$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';
}
}
Тоді як про те, !next( $array )
щоб знайти останню, $value
яка повернеться, true
якщо її немаєnext()
значення для ітерації.
І я вважаю за краще використовувати for
цикл замість того, foreach
якби я збирався використовувати лічильник, як це:
$len = count( $array );
for ( $i = 0; $i < $len; $i++ ) {
$value = $array[$i];
if ($i === 0) {
// first
} elseif ( $i === $len - 1 ) {
// last
}
// …
$i++;
}
Я натрапив на цю нитку, коли у мене однакова проблема. Мені потрібно лише отримати перший елемент, після чого я повторно проаналізую свій код, поки це не прийшло мені в голову.
$firstElement = true;
foreach ($reportData->result() as $row)
{
if($firstElement) { echo "first element"; $firstElement=false; }
// Other lines of codes here
}
Наведені вище коди є чудовими та повними, але якщо вам потрібен лише перший елемент, тоді ви можете спробувати цей код.
Не впевнений, чи все-таки це необхідно. Але наступне рішення має працювати з ітераторами і не вимагає 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;
}
}
}
Ви також можете використовувати анонімну функцію:
$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
}
});
Слід зазначити ще три речі:
array_values
спочатку.$element
ви повинні передати його посиланням ( &$element
).$indexOfLastElement
внутрішньою use
конструкцією, знову ж таки за посиланням, якщо потрібно.Ви можете використовувати довжину лічильника та масиву.
$ масив = масив (1,2,3,4); $ i = 0; $ len = count ($ масив); foreach ($ масив як $ item) { якщо ($ i === 0) { // спочатку } else if ($ i === $ len - 1) { // останній } //… $ 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();
}
}
Використання скидання ($ масив) та закінчення ($ масив)
<?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>";
}
}
Спробуйте це:
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
таarray_pop
. Хоча це рішення, яке я придумав, якби мені довелося реалізувати таке, я зараз дотримуюся відповіді Рока Краля .