PHP: последний элемент foreach. Альтернативнвый вариант.
3 апреля 2008
Один вариант уже был (для сравнения его тоже приведу), теперь ещё один:
foreach ($array as $key => $value) {
if($value == end($array)) {
// делаем что-либо с последним элементом...
}
else {
// делаем что-либо с каждым элементом
}
}
foreach ($array as $key => $value) {
if (!next($array)) {
// делаем что-либо с последним элементом...
}
else {
// делаем что-либо с каждым элементом
}
}
edit1:
Спасибо dkrnl. Устроил тест.
Вариант №1 работает только если явно задать ключи:
$array = array('1' => '1','2' => '2','3' => '3', '4'=>'4','5'=>'5');
Вариант №2 работает только если массив передать по ссылке:
$array = new ArrayObject(array(1,2,3,4,5));
Работающий в любом случае вариант:
$total = count($array);
$counter = 0;
foreach($array as $key => value){
$counter++;
if($counter == $total){
// делаем что-либо с последним элементом...
}
else{
// делаем что-либо с каждым элементом
}
}
edit2:
А ведь и правда стало смахивать на for :) Неудобство в том, что при обращении к элементу в случае с for придётся использовать индекс.
edit3:
Неплохое решение DeadLy:
$end_element = array_pop($array);
foreach ($array as $value) {
// делаем что-либо с каждым элементом
}
// делаем что-либо с последним элементом $end_element
Комментарии RSS по email OK
это не рабочий код - внутри foreach нельзя перемешать(reset,end,next...) внутренний указатель перебираемого массива.
Да, кое-где работает, но не желательно такое использовать, не на всех серверах сработает
dkrnl
Попробуйте.
mAd
И как это зависит от сервера?
код:
результат:
php: 5.2.4
v1:
1, 2, 3, 4, 5,
v2:
1, 2, 3, 45
В первом случаи все безтолку, во втором внутрений указатель "калбасит".
про end:
mixed end ( array &$array )
end() устанавливает внутренний указатель array на последний элемент и возвращает его значение.
про next:
mixed next ( array &$array )
Возвращает значение элемента массива, находящегося на позиции, следующей за позицией, в которой находится его внутренний указатель или FALSE, если достигнут конец массива.
про foreach:
Замечание: When foreach first starts executing, the internal array pointer is automatically reset to the first element of the array. This means that you do not need to call reset() before a foreach loop.
Замечание: Unless the array is referenced, foreach operates on a copy of the specified array and not the array itself. foreach has some side effects on the array pointer. Don't rely on the array pointer during or after the foreach without resetting it.
Да, дествительно...
Вариант №1 работает только если явно задать ключи:
Вариант №2 работает только если массив передать по ссылке:
Работающий в любом случае вариант:
Если нужно знать последний элемент массива, то лучше через for сделать
Ну, на самом деле да :)
Хотя придётся указывать индексы...
"И как это зависит от сервера?"
сужу только по своему опыту
Делал так в одном из проектов, локально работало, на хостинге фирмы тоже работало, залили на хостинг заказчика перестало работать, не end не next в foreach корректно не работал. причину выяснять времени небыло, быстрее было переписать на for.
Ну, скорее это зависило от версии PHP, нежели от сервера. Вообще, как видно, вприанты с for и счётчиком - единственные стабильные из рассмотренных.
Ну, это не совсем то: нам нужно сделать с последним что-то уникальное. Допустим, вывести все на печать с запятой, а последний - с точкой.
Почему же не то?
Извиняюсь, перепутал array_pop с end :) Хорошее решение. Добавлю к основной заметке.
а вообще если просто вывести 1,2,3,4,5
то можно
Эмм, народ, вы меня умиляете.
Есть два простейших способа.
Первый заключается в том, что бы генерировать листинг тагов зарание правильно:
Второй, когда уже имеем готовую строку:
nix
http://lv.php.net/manual/ru/function.join.php
join — Псевдоним функции implode()
Psih
За напоминание о join спасибо.
Список тэгов — всего лишь пример. Задача — исключительно обработать последний элемент массива.
А можно просто использовать implode или explode Где разделитель ", "
:-))
Удачи!
У вас в первом примере в условии 1 скобки не хватает.
PS. Извиняюсь за некропост, просто решение искал и на ваш блог наткнулся ;)
Кирилл, поправил, спасибо.
Не поможет implode когда разделителем станет не запятушечка, а некий код. Тут уже надо какой-нить count приделывать. Типа:
Ну, а уж если ключи вас беспокоят, то:
Что-то никто за 7 лет не вспомнил про key(), так что я тут тоже понекропощу :)
Предлагаю опубликовать это сниппетом на gostash.it
reinq, готово.
Использовать нужно в зависимости от задачи. Если целостный массив далее не будет использоваться, то отлично подойдет array_pop, ну или тогда не забудьте подконектить его назад. Для определения последнего значения непосредственно в цикле, само стабильное и простое.
саму count естественно лучше использовать до цикла, для повышения производительности. Но я думаю смысл всем ясен)
Ребят, я реализовываю в своих проектах это дело так -
Ну разумеется - тут логика понятна? Это я просто шаблонизатор еще использую)
Кстати, админ - нажимаю на кнопку "код" - ни ответа, ни привета :D
Дмитрий, да, кнопочки отломались. Пора переписать...
Хочется и свои 5 копеек вставить, ибо тут прям неплохо описаны советы, хорошая подборка. Самый лайфаковый метод был от DeadLy, но это довольно не хорошо в плане кода. Так вот, у меня проблема была - что в массивах может быть что угодно - гипер-вложенные массивы, огромных размеров, и при этом значения всевозможные, в том числе и null. Конечно самый простой, надёжный и универсальный способ это - for. Но для форыча, я немного дополнил под свою задачу один из ваших вариантов (слава пользователю Kost!) и сделал следующую конструкцию:
if(!next($array) && !key($array)){ ...что-то делаем с последним }
Ребзя, я так делаю:
foreach(...) { if(@$i++ == 0) ... }
Кстати можно и:
if (!@$i++) ...
:)
Зачем каунтер если есть $key в цикле?
В первом решении ошибка. End возвращает не ключ, а значение. Вот и сравнивать нужно с ним.
if($value== end($array)) {
Андрей, поправил. Спасибо.
if($value== end($array)) {
А если значения не уникальные, то при первом совпадении будет считаться последним элемент, хотя элементов может быть много.
Например: ["название", "стоимость", "базовая валюта", "количество", "общая сумма", "валюта расчета"]
третий и последний элементы по значениям могут быть одинаковые
Работает! В закладки.
foreach($arr as $key => $value){ if($key == array_key_last($arr)) ... else ... }