PHP: последний элемент foreach. Альтернативнвый вариант.

Четверг, 3 апреля 2008

Один вариант уже был (для сравнения его тоже приведу), теперь ещё один:


foreach ($array as $key => $value) {
if($key == end($array) {
// делаем что-либо с последним элементом...
}
else {
// делаем что-либо с каждым элементом
}
}



Вариант Kost


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

Тэги:

Комментарии

#1 dkrnl 03.04.08, 13:29

это не рабочий код - внутри foreach нельзя перемешать(reset,end,next...) внутренний указатель перебираемого массива.

#2 mAd 03.04.08, 13:36

Да, кое-где работает, но не желательно такое использовать, не на всех серверах сработает

#3 Sam 03.04.08, 14:19

dkrnl
Попробуйте.

mAd
И как это зависит от сервера?

#4 dkrnl 03.04.08, 14:55

код:



echo "php: ", PHP_VERSION;

echo "<hr>";

echo "v1:<br>";
$array = array(1,2,3,4,5);
foreach ($array as $key => $value)
{
echo $value;
if($key != end($array))
{
echo ", ";
}
}

echo "<hr>";

echo "v2:<br>";
foreach ($array as $key => $value)
{
echo $value;
if (next($array))
{
echo ", ";
}
}



результат:
php: 5.2.4
--------------------------------------------------------------------------------
v1:
1, 2, 3, 4, 5,
--------------------------------------------------------------------------------
v2:
1, 2, 3, 45

В первом случаи все безтолку, во втором внутрений указатель "калбасит".

#5 dkrnl 03.04.08, 15:02

про 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.

#6 Sam 03.04.08, 15:51

Да, дествительно...

Вариант №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 {
// делаем что-либо с каждым элементом
}
}

#7 Денис Радченко 03.04.08, 17:55

Если нужно знать последний элемент массива, то лучше через for сделать

#8 Sam 03.04.08, 18:13

Ну, на самом деле да :)

#9 Sam 03.04.08, 18:19

Хотя придётся указывать индексы...

#10 mAd 03.04.08, 19:22

"И как это зависит от сервера?"

сужу только по своему опыту
Делал так в одном из проектов, локально работало, на хостинге фирмы тоже работало, залили на хостинг заказчика перестало работать, не end не next в foreach корректно не работал. причину выяснять времени небыло, быстрее было переписать на for.

#11 Sam 03.04.08, 19:38

Ну, скорее это зависило от версии PHP, нежели от сервера. Вообще, как видно, вприанты с for и счётчиком - единственные стабильные из рассмотренных.

#12 DeadLy 04.04.08, 09:51

$end_element = array_pop($array);
foreach ($array as $value) {
// делаем что-либо с каждым элементом
}
// делаем что-либо с последним элементом...

#13 Sam 04.04.08, 13:15

Ну, это не совсем то: нам нужно сделать с последним что-то уникальное. Допустим, вывести все на печать с запятой, а последний - с точкой.

#14 DeadLy 04.04.08, 14:07

Почему же не то?

$array = array(1,2,3);
$end_element = array_pop($array);
foreach ($array as $value) {
echo $value.' - !';
}
echo $end_element.' - Последний элемент';

#15 Sam 04.04.08, 14:11

Извиняюсь, перепутал array_pop с end :) Хорошее решение. Добавлю к основной заметке.

#16 DeadLy 04.04.08, 14:16

а вообще если просто вывести 1,2,3,4,5
то можно
$values = '1,2,3,4,5,'; // результат работы foreach
$values = substr($values,0,-1);
echo $values; //результат 1,2,3,4,5

#17 Psih 17.07.08, 17:54

Эмм, народ, вы меня умиляете.
Есть два простейших способа.

Первый заключается в том, что бы генерировать листинг тагов зарание правильно:
$tag_list = Array();
foreach ($someDataSource as $item) {
// code here
$tag_list[] = $item['someTagData']
}
$tag_list = implode(',', $tag_list);
echo $tag_list; // tag1, tag2, ...., tagN

Второй, когда уже имеем готовую строку:
$str = 'tag1, tag2, ..., tagN,';
$str = trim($str, ',');

#18 nix 17.07.08, 17:54

echo join(', ', $array)

#19 Psih 17.07.08, 17:58

nix

http://lv.php.net/manual/ru/function.join.php
join — Псевдоним функции implode()

#20 Sam 17.07.08, 18:24

Psih
За напоминание о join спасибо.
Список тэгов — всего лишь пример. Задача — исключительно обработать последний элемент массива.

#21 Artur 24.07.08, 11:28

А можно просто использовать implode или explode Где разделитель ", "
:-))
Удачи!

Оставить комментарий




Подписаться на RSS

Интересное

Разделы

  1. (5)
  2. (11)
  3. (6)
  4. (9)
  5. (6)
  6. (6)
  7. (16)
  8. (60)
  9. (274)
  10. (52)
  11. (16)
  12. (12)
  13. (37)
  14. (6)
  15. (10)
  16. (14)
  17. (18)
  18. (16)
  19. (7)
  20. (8)
  21. (7)
  22. (7)
  23. (31)
  24. (76)
  25. (27)
  26. (68)
  27. (5)
  28. (203)
  29. (59)
  30. (6)
  31. (19)
  32. (73)
  33. (27)
  34. (70)
  35. (33)
  36. (10)
  37. (5)
  38. (6)
  39. (5)
  40. (341)
  41. (14)
  42. (11)
  43. (6)
  44. (13)
  45. (8)
  46. (18)
  47. (6)
  48. (15)
  49. (115)
  50. (18)
  51. (6)
  52. (9)
  53. (71)
  54. (16)
  55. (6)
  56. (25)
  57. (13)
  58. (5)
  59. (39)
  60. (7)
  61. (31)
  62. (7)
  63. (12)
  64. (11)
  65. (124)
  66. (34)
  67. (5)
  68. (18)
  69. (28)
  70. (9)
  71. (6)
  72. (8)
  73. (41)
  74. (10)
  75. (6)
  76. (12)
  77. (5)
  78. (9)
  79. (6)

Друзья