Php foreach узнать номер итерации

PHP How to determine the first and last iteration in a foreach loop?

You should update the question with PHP. Javascript has forEach loop too. Viewers can get a misleading answer.

@Maidul True, in google it’s not clear at all that it’s about PHP so I added the word «PHP» to the title for clarity.

21 Answers 21

If you prefer a solution that does not require the initialization of the counter outside the loop, then you can compare the current iteration key against the function that tells you the last / first key of the array.

PHP 7.3 and newer:

foreach ($array as $key => $element) < if ($key === array_key_first($array)) < echo 'FIRST ELEMENT!'; >if ($key === array_key_last($array)) < echo 'LAST ELEMENT!'; >> 

PHP 7.2 and older:

PHP 7.2 is already EOL (end of life), so this is here just for historic reference. Avoid using.

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

This should bubble all the way to the top because it is the right answer. Another advantage of these functions over using array_shift and array_pop is that the arrays are left intact, in case they are needed at a later point. +1 for sharing knowledge just for the sake of it.

this is definitely the best way if you’re wanting to keep your code clean. I was about to upvote it, but now I’m not convinced the functional overhead of those array methods is worth it. If we’re just talking about the last element then that is end() + key() over every iteration of the loop — if it’s both then that’s 4 methods being called every time. Granted, those would be very lightweight operations and are probably just pointer lookups, but then the docs do go on to specify that reset() and end() modify the array’s internal pointer — so is it quicker than a counter? possibly not.

I don’t think you should issue reset($array) inside a foreach. From the official documentation (www.php.net/foreach): «As foreach relies on the internal array pointer changing it within the loop may lead to unexpected behavior.» And reset does precisely that (www.php.net/reset): «Set the internal pointer of an array to its first element»

@GonçaloQueirós: It works. Foreach works on a copy of array. However, if you are still concerned, feel free to move the reset() call before the foreach and cache the result in $first .

I don’t get why you all upvote this. Just use a boolean for «first» thats just better than everything else. The accepted answer is the way to go without running into «special cases».

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

I do not think downvoting should take place here as this is also working correctly and is still not so rubbish as using array_shift and array_pop . Though this is the solution I’d came up if I had to implement such a thing, I’d stick with the Rok Kralj’s answer now on.

Читайте также:  Jar file to java code

@Twan How is point #3 right? Or relevant at all to this question since it involves HTML? This is a PHP question, clearly. and when it comes to mark-up semantics, it’s down to a much deeper facts than «a proper blahblah is always better than blahblah (this is not even my opinion, it’s pure fact)»

To find the last item, I find this piece of code works every time:

@Kevin Kuyl — As mentioned by Pang above, if the array contains an item that PHP evaluates as false (i.e. 0, «», null) this method will have unexpected results. I’ve amended the code to use ===

this is mostly very awesome but to clarify to problem others are pointing out it will invariably fail with an array like [true,true,false,true] . But personally I will be using this anytime I am dealing with an array that doesn’t contain boolean false .

next() should NEVER be used inside a foreach loop. It messes up the internal array pointer. Check out the documentation for more info.

A more simplified version of the above and presuming you’re not using custom indexes.

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

Version 2 — Because I have come to loathe using the else unless necessary.

$len = count($array); foreach ($array as $index => $item) < if ($index == 0) < // first // do something continue; >if ($index == $len - 1) < // last // do something continue; >> 

This is best answer for me but should be condensed, no point declaring length outside the foreach loop: if ($index == count($array)-1) < . >

@peteroak Yes actually it would technically hurts performance, and depending what your counting or how many loops could be significant. So disregard my comment 😀

@peteroak @Andrew The total number of elements in an array is stored as a property internally, so there would not be any performance hits by doing if ($index == count($array) — 1) . See here.

You could remove the first and last elements off the array and process them separately.

Removing all the formatting to CSS instead of inline tags would improve your code and speed up load time.

You could also avoid mixing HTML with php logic whenever possible.

Your page could be made a lot more readable and maintainable by separating things like this:

 function show_subcat($val) < ?> 
function show_cat($item) < ?>
$item['xcatid'])) ; foreach($subcat as $val) show_subcat($val); ?>
function show_collection($c) < ?>
$c['xcollectionid'])); foreach($cat as $item) show_cat($item); ?>
?>

I like the idea of last (removing the last element from the array), so that I can generate the last element differently without checking at every loop.

An attempt to find the first would be:

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

Please edit your answer to add an explanation of how your code works and how it solves the OP’s problem. Many SO posters are newbies and will not understand the code you have posted.

This answer doesn’t say how to determine if you’re in the last iteration of the loop. It is, however, a valid attempt at an answer, and shouldn’t be flagged as not an answer. If you don’t like it, you should down vote it, not flag it.

It’s clear , in the first iteration he will enter the first condition and then changes it value to false , and this way it will only get into first iteration once.

// Set the array pointer to the last key end($array); // Store the last key $lastkey = key($array); foreach($array as $key => $element)

Thank you @billynoah for your sorting out the end issue.

@Sydwell — read the error. key() is getting an integer, not end() . end() «returns the value of the last element«, and key() expects an array as input.

1: Why not use a simple for statement? Assuming you’re using a real array and not an Iterator you could easily check whether the counter variable is 0 or one less than the whole number of elements. In my opinion this is the most clean and understandable solution.

$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: You should consider using Nested Sets to store your tree structure. Additionally you can improve the whole thing by using recursive functions.

If you’re going to use a for you can loop from 1 to n-1 and take the if s out of the body. No point checking them repeatedly.

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

It is fast and easy as long as you can be sure there are always more than one lement in the array (as Memochipan said). So it’s not a failsafe solution for me — no ‘best answer’.

The most efficient answer from @morg, unlike foreach , only works for proper arrays, not hash map objects. This answer avoids the overhead of a conditional statement for every iteration of the loop, as in most of these answers (including the accepted answer) by specifically handling the first and last element, and looping over the middle elements.

The array_keys function can be used to make the efficient answer work like 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++; 

I haven’t done benchmarking on this, but no logic has been added to the loop, which is were the biggest hit to performance happens, so I’d suspect that the benchmarks provided with the efficient answer are pretty close.

If you wanted to functionalize this kind of thing, I’ve taken a swing at such an iterateList function here. Although, you might want to benchmark the gist code if you’re super concerned about efficiency. I’m not sure how much overhead all the function invocation introduces.

Источник

как получить номер итерации при переборе объекта в php циклом foreach?

введите сюда описание изображения

как получить номер итерации при переборе объекта в php циклом foreach или массива, где ключ не число, а название, но надо получить его положение или номер итерации?

2 ответа 2

Это просто заведи переменную со счетчиком:

 "Kevin", "last_name" => "Skoglund", "address" => "123 main street", "city" => "Baverly Hils", "state" => "CA", "zip_code" => "90210" ); foreach ($person as $value) < $counter++; // тут твой код >

В переменной $counter всегда теперь находится номер итерации.

и для каждого масива перед циклом предется придумывать новое имя переменной или можно использовать эту?

$person = [ "first_name" => "Kevin", "last_name" => "Skoglund", "address" => "123 main street", "city" => "Baverly Hils", "state" => "CA", "zip_code" => "90210" ]; $idx = array_search("zip_code", array_keys($person)); // $idx = 5 

Похожие

Подписаться на ленту

Для подписки на ленту скопируйте и вставьте эту ссылку в вашу программу для чтения RSS.

Дизайн сайта / логотип © 2023 Stack Exchange Inc; пользовательские материалы лицензированы в соответствии с CC BY-SA . rev 2023.7.27.43548

Нажимая «Принять все файлы cookie» вы соглашаетесь, что Stack Exchange может хранить файлы cookie на вашем устройстве и раскрывать информацию в соответствии с нашей Политикой в отношении файлов cookie.

Источник

How to get Array index in foreach

I have a foreach loop in php to iterate an associative array. Within the loop, instead of increamenting a variable I want to get numeric index of current element. Is it possible.

$arr = array('name'=>'My name','creditcard'=>'234343435355','ssn'=>1450); foreach($arr as $person) < // want index here >
$arr = array('name'=>'My name','creditcard'=>'234343435355','ssn'=>1450); $counter =0; foreach($arr as $person) < // do a stuff $counter++; >

2 Answers 2

Use this syntax to foreach to access the key (as $index ) and the value (as $person )

foreach ($arr as $index => $person)

Why would you need a numeric index inside associative array? Associative array maps arbitrary values to arbitrary values, like in your example, strings to strings and numbers:

$assoc = [ 'name'=>'My name', 'creditcard'=>'234343435355', 'ssn'=>1450 ]; 

Numeric arrays map consecutive numbers to arbitrary values. In your example if we remove all string keys, numbering will be like this:

$numb = [ 0=>'My name', 1=>'234343435355', 2=>1450 ]; 

In PHP you don’t have to specify keys in this case, it generates them itself. Now, to get keys in foreach statement, you use the following form, like @MichaelBerkowski already shown you:

foreach ($arr as $index => $value) 

If you iterate over numbered array, $index will have number values. If you iterate over assoc array, it’ll have values of keys you specified.

Seriously, why I am even describing all that?! It’s common knowledge straight from the manual!

Now, if you have an associative array with some arbitrary keys and you must know numbered position of the values and you don’t care about keys, you can iterate over result of array_values on your array:

foreach (array_values($assoc) as $value) // etc 

But if you do care about keys, you have to use additional counter, like you shown yourself:

$counter = 0; foreach ($assoc as $key => $value) < // do stuff with $key and $value ++$counter; >

Or some screwed functional-style stuff with array_reduce , doesn’t matter.

Источник

Оцените статью