Intereting Posts
mysqli_query – возвращаемые значения «Строгие стандарты: только переменные должны передаваться по ссылке» error PHP для EasyPHP MySQL сервер 1 секунда задержки соединения Добавление тегов к выбору Как застегнуть 100 мб файлов во время (до) загрузки, чтобы скорость загрузки могла быть увеличена? PHP: конвертировать любую строку в UTF-8 без знания исходного набора символов или, по крайней мере, попробовать Как отправить этот XML-файл с помощью SOAP и PHP PHP7 method_exists Неисправность Ошибка: имя функции должно быть строкой bootstrap 3 разбиение на страницы с помощью codeigniter как изменить значение с помощью переключателей Преимущества MySQLi над MySQL Как выполнить команду оболочки из скрипта php Знание с помощью PHP, если браузер может воспроизводить аудиофайл с помощью тега html5 audio Значение коэффициента обменного курса PHP grab json из ответа API Столбец Mysql полностью работает в PhpMyadmin, но не с Php mysqli_query ()

Как определить первую и последнюю итерацию в цикле foreach?

Вопрос прост. У меня есть цикл foreach в моем коде:

 foreach($array as $element) { //code } 

В этом цикле я хочу реагировать по-разному, когда мы находимся на первой или последней итерации.

Как это сделать?

Related of "Как определить первую и последнюю итерацию в цикле foreach?"

Вы можете использовать счетчик:

 $i = 0; $len = count($array); foreach ($array as $item) { if ($i == 0) { // first } else if ($i == $len - 1) { // last } // … $i++; } 

Если ваш массив имеет уникальные значения массива, то определение первого и последнего элемента тривиально:

 foreach($array as $element) { if ($element === reset($array)) echo 'FIRST ELEMENT!'; if ($element === end($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!'; } 

Обновление: некоторые люди обеспокоены производительностью и / или изменением указателя массива внутри цикла foreach. Для них вы можете кэшировать значение ключа перед циклом.

 reset($array); $first = key($array); foreach($array as $key => $element) { if ($key === $first) echo 'FIRST ELEMENT!'; } 

Чтобы найти последний элемент, я считаю, что этот кусок кода работает каждый раз:

 foreach( $items as $item ) { if( !next( $items ) ) { echo 'Last Item'; } } 

Более упрощенная версия вышеизложенного и предполагающая, что вы не используете пользовательские индексы …

 $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; } } 

Вы можете удалить первый и последний элементы из массива и обработать их отдельно.
Как это:

 <?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) { //retirive 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 } } 

Просто это работает!

 //Store the last key $lastkey = key(end($array)); foreach($array as $key => $element) { ....do array stuff if ($lastkey === key($array)) echo 'LAST ELEMENT!'; } 

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: Вы должны использовать Nested Sets для хранения вашей древовидной структуры. Кроме того, вы можете улучшить все это, используя рекурсивные функции.

Лучший ответ:

 $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"; } 

Для сценариев генерации 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++; в $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 миллисекунд

И вполне понятно, что проверка стоит много, и, конечно же, становится еще хуже, чем больше проверяет переменные;)

Использование логической переменной по-прежнему является самым надежным, даже если вы хотите проверить первое появление значения $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++; } 

С ключами и значениями это работает также:

 foreach ($array as $key => $value) { if ($value === end($array)) { echo "LAST ELEMENT!"; } } 

Самый эффективный ответ от @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++; в $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 . Хотя, возможно, вы захотите провести сравнение кода gist, если вы серьезно обеспокоены эффективностью. Я не уверен, сколько накладных расходов вызывает все функции invocation.

Я столкнулся с этим вопросом, когда у меня такая же проблема. Мне нужно только получить первый элемент, тогда я переанализирую свой код, пока это не придет мне в голову.

 $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 свой массив через array_values .
  • Если вам нужно изменить $element вы должны передать его по ссылке ( &$element ).
  • Любые переменные извне анонимной функции, которые вам нужны внутри, вам нужно будет перечислить их рядом с $indexOfLastElement внутри use конструкции, опять же по ссылке, если необходимо.

Попробуй это:

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