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

Вопрос простой. В моем коде есть цикл foreach:

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

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

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


person mehdi    schedule 01.07.2009    source источник
comment
Вам следует обновить вопрос с помощью PHP. В Javascript также есть цикл forEach. Зрители могут получить вводящий в заблуждение ответ.   -  person Maidul    schedule 12.03.2021


Ответы (19)


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

$i = 0;
$len = count($array);
foreach ($array as $item) {
    if ($i == 0) {
        // first
    } else if ($i == $len - 1) {
        // last
    }
    // …
    $i++;
}
person Gumbo    schedule 01.07.2009
comment
Я не думаю, что здесь должно происходить голосование против, так как это тоже работает правильно и все же не такая ерунда, как использование array_shift и array_pop. Хотя это решение, которое я придумал, если бы мне пришлось реализовать такую ​​вещь, я бы сейчас придерживался ответа Рока Краля. - person shadyyx; 15.05.2013
comment
Если мне нужен счетчик, я предпочитаю использовать цикл FOR вместо FOREACH. - person rkawano; 15.11.2014
comment
Если вы используете $i = 1, вам не нужно беспокоиться о $len - 1, просто используйте $len. - person aksu; 03.04.2015
comment
@Deji Почему третий пункт неверен? Это более чистый способ использовать список вместо div для каждого отдельного элемента. - person ; 22.12.2015
comment
@Twan Как пункт № 3 правильный? Или вообще имеет отношение к этому вопросу, поскольку он включает HTML? Ясно, что это вопрос PHP ... и когда дело доходит до семантики разметки, все сводится к гораздо более глубоким фактам, чем правильный бла-бла всегда лучше, чем бла-бла (это даже не мое мнение, это чистый факт) - person Deji; 23.12.2015
comment
@Deji Я думаю, что вопрос изначально содержал довольно много HTML (до того, как Рок отредактировал его, чтобы сделать его чище - '14) . - person Cullub; 02.02.2016
comment
@rkawano, но вы не можете получить именованный ключ, если используете цикл FOR - person Fahmi; 03.09.2016
comment
Почему бы не использовать в таких случаях обычный цикл for? Если вам нужно указать, где вы находитесь в цикле, это кажется наиболее логичным способом. Счетчик просто имитирует это - person Kellen Stuart; 19.07.2017
comment
@KolobCanyon - причина в том, что цикл for не работает с ассоциативным массивом. - person billynoah; 28.12.2018
comment
На самом деле ответ Рока Краля - это то, что многие из нас искали. Но требование для PHP 7.3 означает использование array_key_first и array_key_last означает, что это действительно тот метод, который мы должны использовать для создания переносимого кода. Спасибо. - person hiburn8; 07.02.2019
comment
Вам не нужно объявлять переменную $i, просто используйте индекс foreach: foreach ($array as $index => $item) { затем в остальной части кода замените все $i на $index. - person Fellipe Sanches; 04.12.2019
comment
Тогда почему бы не использовать цикл for? - person Musa Haidari; 05.06.2020

Если вы предпочитаете решение, которое не требует инициализации счетчика вне цикла, я предлагаю сравнить текущий ключ итерации с функцией, которая сообщает вам последний / первый ключ массива.

Это станет несколько более эффективным (и более читаемым) с выходом PHP 7.3.

Решение для 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!';
}

Решение для всех версий PHP:

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

    end($array);
    if ($key === key($array))
        echo 'LAST ELEMENT!';
}
person Rok Kralj    schedule 08.01.2012
comment
Фантастический ответ! Намного чище, чем использование множества массивов. - person Paul J; 16.02.2012
comment
Это должно подняться до самого верха, потому что это правильный ответ. Еще одно преимущество этих функций перед использованием array_shift и array_pop состоит в том, что массивы остаются нетронутыми, на случай, если они понадобятся позже. +1 за обмен знаниями просто ради. - person Awemo; 30.04.2012
comment
Он должен пузыриться до самого верха, так как он самый чистый! - person user776686; 07.06.2012
comment
это определенно лучший способ, если вы хотите, чтобы ваш код был чистым. Я собирался проголосовать за него, но теперь я не уверен, что функциональные издержки этих методов массива того стоят. Если мы говорим только о последнем элементе, то это end() + key() на каждой итерации цикла - если оба, то каждый раз вызывается 4 метода. Конечно, это были бы очень легкие операции и, вероятно, просто поиск указателя, но затем в документации указывается, что reset() и end() изменяют внутренний указатель массива - так что это быстрее, чем счетчик? возможно, нет. - person pospi; 20.06.2012
comment
Если вас беспокоит эта минимальная оптимизация, вы можете кэшировать key () в переменную до области цикла for. Но, как я уже сказал, не беспокойтесь об этом. - person Rok Kralj; 21.06.2012
comment
Я не думаю, что вам следует выполнять reset ($ array) внутри foreach. Из официальной документации (www.php.net/foreach): поскольку foreach полагается на указатель внутреннего массива, его изменение в цикле может привести к неожиданному поведению. И reset делает именно это (www.php.net/reset): устанавливает внутренний указатель массива на его первый элемент. - person Gonçalo Queirós; 15.01.2013
comment
@ GonçaloQueirós: Это работает. Foreach работает с копией массива. Однако, если вы все еще обеспокоены, не стесняйтесь переместить вызов reset() перед foreach и кэшировать результат в $first. - person Rok Kralj; 17.01.2013
comment
подождите, а что будет, если я сравню $element с $array[0]? - person Chibueze Opata; 12.03.2013
comment
Это работает, если у вас есть последовательный массив. Например, это не сработает, если бы у вас было $array = array('a' => 1, 'b' => 2), тогда $array[0] вернет NULL и выдаст уведомление. - person Rok Kralj; 12.03.2013
comment
Как сказал Гонсало, обратите внимание, что здесь вы не можете использовать указатель. т.е. - foreach($array as $key=>&$value). В этом случае он сбросит счетчик итераций. Использовать стандартный foreach($array as $key=>$value) - person Mladen Janjetovic; 16.05.2013
comment
Согласовано. Отличный, простой и элегантный ответ. Я ненавижу глупые счетчики в циклах, так что это действительно меняет мою точку зрения на итерацию ассоциативного массива. Фантастика! - person Giacomo1968; 08.08.2013
comment
Имейте в виду, что добавленное обновленное (последнее) решение скопирует весь массив и будет использовать дважды память. Используйте isLast (& $ array, $ key), чтобы предотвратить это. - person dompie; 17.02.2014
comment
Обратите внимание, что с этим последним обновлением (с использованием last(&$array, $key)) вы фактически установите указатель исходного массива на последний элемент. Без & этого не произойдет, потому что это копия исходного массива. Я бы удалил &. Эта функция потребляет больше памяти, но может предотвратить некоторые неожиданные действия. - person dbroeks; 07.03.2014
comment
Я не понимаю, почему вы все это поддерживаете. Просто используйте логическое значение для первого, это лучше, чем все остальное. Принятый ответ - это способ обойтись без особых случаев. - person OderWat; 08.10.2015
comment
Этот ответ действителен, если вы используете простые массивы, над которыми вы полностью контролируете, но если вы используете объекты из платформы / фреймворка, с которыми вы не решаетесь действительно возиться, тогда ответ Гамбо подходит лучше - person DM8; 16.02.2018
comment
1 вкладыш: if (end ($ array) && $ key === key ($ array)) { - person Andrew; 08.12.2018

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

foreach( $items as $item ) {
    if( !next( $items ) ) {
        echo 'Last Item';
    }
}
person Yojance    schedule 16.08.2014
comment
У него слишком мало голосов, есть ли недостатки в его использовании? - person Kevin Kuyl; 20.04.2016
comment
@Kevin Kuyl - как упоминалось выше Пангом, если массив содержит элемент, который PHP оценивает как ложный (то есть 0`` null), этот метод будет иметь неожиданные результаты. Я изменил код, чтобы использовать === - person Eric Kigathi; 01.09.2016
comment
Поэтому я предполагаю, что вы замените (! Next ($ items)) на (next ($ items) === FALSE). Я не эксперт по php, поэтому просто хотел проверить. - person PedroKTFC; 10.12.2016
comment
это в основном очень круто, но, чтобы прояснить проблему, другие указывают, что с массивом типа [true,true,false,true] он неизменно терпит неудачу. Но лично я буду использовать это в любое время, когда буду иметь дело с массивом, не содержащим логического false. - person billynoah; 10.01.2017
comment
Я получаю очень странное поведение с этой next() проверкой в ​​цикле foreach, это действительно сложный фрагмент кода. Во-первых, я получаю два уведомления о последнем элементе, а во-вторых, когда next() вызывается несколько раз (например, в двух разных условиях), происходят чрезвычайно странные вещи. Похоже, что у next() и foreach() есть свой собственный указатель на массив. Проверено на PHP 5.5.20. - person mvds; 16.10.2017
comment
next() не следует НИКОГДА использовать внутри цикла foreach. Это портит внутренний указатель массива. Ознакомьтесь с документацией для получения дополнительной информации. - person Drazzah; 17.01.2018
comment
Престижность за этот ответ. Так просто и полностью поддерживает более ранние версии PHP. - person ; 02.10.2019

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

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

Версия 2 - Потому что я ненавижу использовать else без необходимости.

$len = count($array);
foreach ($array as $index => $item) {
    if ($index == 0) {
        // first
        // do something
        continue;
    }

    if ($index == $len - 1) {
        // last
        // do something
        continue;
    }
}
person Hayden    schedule 11.12.2010
comment
Это работает и для объектов. Остальные решения работают только с массивами. - person Yasen; 30.01.2014
comment
Это лучший ответ для меня, но его следует сжать, не имеет смысла объявлять длину вне цикла foreach: if ($ index == count ($ array) -1) {...} - person Andrew; 22.10.2015
comment
@Andrew таким образом вы продолжаете считать элементы массива для каждой итерации. - person pcarvalho; 13.07.2016
comment
@peteroak Да, на самом деле это технически повредит производительности, и в зависимости от ваших подсчетов или количества циклов, которые могут быть значительными. Так что не обращайте внимания на мой комментарий: D - person Andrew; 13.07.2016
comment
@peteroak @Andrew Общее количество элементов в массиве хранится как свойство внутри, поэтому выполнение if ($index == count($array) - 1) не приведет к снижению производительности. См. здесь. - person Katrina; 26.08.2016
comment
@GreeKatrina Хорошая находка! Итак, поскольку производительность не обязательно будет проблемой, все остальное зависит только от личных предпочтений. - person Hayden; 26.08.2016

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

Нравится:

<?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
}
?>
person Carlos Lima    schedule 01.07.2009
comment
Мне нравится идея last (удаление последнего элемента из массива), чтобы я мог генерировать последний элемент по-разному, не проверяя каждый цикл. - person massimoi; 10.01.2021

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

// 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 за решение проблемы конца.

person Sydwell    schedule 25.10.2015
comment
Лучший! Я бы только пояснил if ($key === $lastkey). - person Krzysztof Przygoda; 23.12.2015
comment
$lastkey будет null, если $array не ассоциативный массив, таким образом нарушает код - person Dadan; 07.09.2016
comment
Так почему ===, а не ==? - person AlexioVay; 29.10.2016
comment
Разве это не должно быть if ($lastkey === $key)? - person Kinetic; 13.01.2017
comment
Я получаю: PHP Warning: key() expects parameter 1 to be array, integer given in php shell code on line 1 - person billynoah; 28.12.2018
comment
@billynoah, скорее всего, вы использовали целочисленную переменную в качестве параметра функции end. Параметр должен быть массивом - person Sydwell; 29.12.2018
comment
@Sydwell - прочтите ошибку. key() получает целое число, а не end(). end() возвращает значение последнего элемента, а key() ожидает в качестве входных данных массив. - person billynoah; 29.12.2018
comment
sandbox.onlinephpfunctions.com/code/ - person billynoah; 29.12.2018

Попытка найти первый будет:

$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
  }
}
person sstauross    schedule 27.10.2014
comment
Отредактируйте свой ответ, чтобы добавить объяснение того, как работает ваш код и как он решает проблему OP. Многие постеры SO - новички и не поймут опубликованный вами код. - person i alarmed alien; 27.10.2014
comment
В этом ответе не говорится, как определить, находитесь ли вы на последней итерации цикла. Однако это действительная попытка ответа, и ее не следует отмечать как не ответ. Если вам это не нравится, вы должны проголосовать против, а не пометить его. - person ArtOfWarfare; 27.10.2014
comment
Понятно, что на первой итерации он войдет в первое условие, а затем изменит его значение на false, и таким образом он попадет в первую итерацию только один раз. - person Mohamed23gharbi; 10.08.2015

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

person okoman    schedule 01.07.2009
comment
Если вы собираетесь использовать for, вы можете сделать цикл от 1 до n-1 и вынуть if из тела. Нет смысла проверять их повторно. - person mpen; 28.01.2016

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

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

}
person Ivan    schedule 11.06.2013
comment
Это не удается, если у вас есть только один элемент в массиве. - person Memochipan; 11.05.2014
comment
Это быстро и просто, если вы можете быть уверены, что в массиве всегда есть более одного элемента (как сказал Memochipan). Так что для меня это не безотказное решение - нет «лучшего ответа». - person Seika85; 14.05.2014
comment
each () УСТАРЕВЛЯЕТСЯ с PHP 7.2.0. См. Также php.net/manual/en/function.each.php - person Flow; 31.07.2017

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

person TheMadDeveloper    schedule 02.07.2016

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

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

person Morg.    schedule 09.08.2011
comment
Ваш код работает только в том случае, если вы можете быть уверены, что вам нужны увеличивающиеся целочисленные ключи. $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: , - person Seika85; 14.05.2014
comment
приведение хеш-карты к массиву является неопределенным поведением, объект array() сделан {'one':"1 1 1",0:"",1:"One",2:"",3:"",4:"Four"}, но пустые элементы игнорируются с помощью count, вы подсчитываете количество определенных вещей !! ПРИХОДИТСЯ ЖЕРТВОСТЬ БОНТИ! Этот ответ заслуживает награды, но если @Morg. ушло, это бессмысленно. Я бы наградил человека, который, вероятно, больше не будет использовать ТАК! Если он вернется и улучшит свой ответ, он заслуживает награды! - person mjz19910; 30.06.2016
comment
Как отмечает @ mjz19910, хеш-карты и массивы не взаимозаменяемы. Однако вы можете получить свойства хэша с помощью функции array_keys, которую вы можете рассматривать как массив. См. мой улучшенный ответ. - person TheMadDeveloper; 02.07.2016
comment
Это то, что я использую для запроса: $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'"; - person Rovshan Mamedov; 05.02.2018

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

foreach ($array as $key => $value) {
    if ($value === end($array)) {
        echo "LAST ELEMENT!";
    }
}
person Benibr    schedule 04.03.2015
comment
Таким образом вы сравниваете значения и не работает, если массив содержит два одинаковых элемента. - person Krzysztof Przygoda; 23.12.2015

Использование логической переменной по-прежнему является наиболее надежным, даже если вы хотите проверить первое появление $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++;
}
person 5ervant - techintel.github.io    schedule 27.09.2015

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

$firstElement = true;

foreach ($reportData->result() as $row) 
{
       if($firstElement) { echo "first element"; $firstElement=false; }
       // Other lines of codes here
}

Приведенные выше коды великолепны и полны, но если вам нужен только первый элемент, вы можете попробовать этот код.

person paul    schedule 11.03.2017

Не уверен, что это еще необходимо. Но следующее решение должно работать с итераторами и не требует 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;
        }
    }
}
person vbarbarosh    schedule 06.04.2015

Использование reset ($ array) и 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>";
        }                

    }

Демо repl.it

person antelove    schedule 18.01.2020

Вы также можете использовать анонимную функцию:

$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, при необходимости снова по ссылке.
person undko    schedule 26.12.2017

Вы можете использовать счетчик и длину массива.

    $array = array(1,2,3,4);

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

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

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);
person PureField    schedule 11.02.2012