548

Is it possible to find the foreach index?

in a for loop as follows:

for ($i = 0; $i < 10; ++$i) {
   echo $i . ' ';
}

$i will give you the index.

Do I have to use the for loop or is there some way to get the index in the foreach loop?

Script47
  • 12,869
  • 4
  • 38
  • 59
user18334
  • 5,573
  • 2
  • 17
  • 7

14 Answers14

1024
foreach($array as $key=>$value) {
    // do stuff
}

$key is the index of each $array element

Giacomo1968
  • 23,903
  • 10
  • 59
  • 92
Owen
  • 76,727
  • 20
  • 113
  • 113
  • 2
    Depends on what the OP means by index: $a = array(3,5,'xx',4312,'sasas'); unset($a[3]); foreach ($a as $k=>$v) print "\$k= $k and \$v = $v"; ?> – Milen A. Radev Sep 27 '08 at 00:21
  • 9
    definitely, this question isn't very specific, i took it to mean the OP was largely unaware of the $key=>$value syntax – Owen Sep 27 '08 at 00:23
  • 48
    well this is actually right, but should not be the accepted answer, since key can be a string too. say you do `$myarr['foo'] = 'bar';` this method fails – Toskan Sep 26 '14 at 06:40
  • 1
    @Toskan Why would it fail? In an associative array the **only** index which exists is the string $key. So `foreach($array as $key=>$value)` would place `"foo"` in the `$key` exactly as you'd expect. Any numerical index could never be mapped to a specific element in the array. At best you could say its the n-th element, but if you were to use `for($i = 0; $i < count($array); $i++)` you could run in to the exact same issue with a numeric array if an index had been `unset()` or if the numeric index was manually decided (like `$array = [2 => "myvariable", "myOtherVariable"]`). – Byson Dec 04 '14 at 10:51
  • 13
    @Bison you are right in the meaning that it does not fail. But it fails to comply the OP question. He is looking for numerical values like the n-th element. – Toskan Dec 08 '14 at 04:12
  • 4
    Like @Toskan says, this should not be the accepted answer. I think it's better to just create a variable outside the loop and count from there, increasing it with `vatiable++;` on each iteration. The traditional way, but has always worked. – Jomar Sevillejo Oct 30 '15 at 01:22
  • Today, visiting this, I found out that iterating over an XML element the $key value always show "entry" because the XML object didn't assigned a numeric value and all the pieces were called "entry". Consider: `$xmlstr = "Title 1Title 2Title 3";` so doing: `$content = SimpleXMLElement($xmlstr);` and then `foreach($content->entry as $key=>$el) {` $key will always show "entry" instead of any unique index that can work to identify the single entry. Using a counter variable was the only choice – LordNeo Apr 06 '18 at 11:59
185

You can put a hack in your foreach, such as a field incremented on each run-through, which is exactly what the for loop gives you in a numerically-indexed array. Such a field would be a pseudo-index that needs manual management (increments, etc).

A foreach will give you your index in the form of your $key value, so such a hack shouldn't be necessary.

e.g., in a foreach

$index = 0;
foreach($data as $key=>$val) {
    // Use $key as an index, or...

    // ... manage the index this way..
    echo "Index is $index\n";
    $index++;
}
buræquete
  • 12,943
  • 4
  • 34
  • 69
ConroyP
  • 38,904
  • 16
  • 76
  • 86
29

It should be noted that you can call key() on any array to find the current key its on. As you can guess current() will return the current value and next() will move the array's pointer to the next element.

Bailey Parker
  • 14,645
  • 3
  • 50
  • 83
  • This should be useful if you want to use a plain old PHP associative array to store data which is to be exposed via the Iterable interface (where you need to keep track of where you are in a loop). – Peter Dec 15 '11 at 21:33
  • 3
    +1 for the alternative, but a function call in every iteration is a little heavier than using preassigned variables (i.e. using the `$key` from `$key=>$value`)... However, I bet the lower performance is non-significant/perceptible in a simple loop. – Armfoot Sep 02 '15 at 15:11
23

Owen has a good answer. If you want just the key, and you are working with an array this might also be useful.

foreach(array_keys($array) as $key) {
//  do stuff
}
Zoredache
  • 31,819
  • 7
  • 40
  • 59
17

You can create $i outside the loop and do $i++ at the bottom of the loop.

Ram Sharma
  • 8,368
  • 7
  • 38
  • 53
Ólafur Waage
  • 64,767
  • 17
  • 135
  • 193
  • 20
    It's important to note that this approach gives the current iteration of the loop, NOT the current index of the iterated array. – Peter Bailey Sep 26 '08 at 19:20
10

These two loops are equivalent (bar the safety railings of course):

for ($i=0; $i<count($things); $i++) { ... }

foreach ($things as $i=>$thing) { ... }

eg

for ($i=0; $i<count($things); $i++) {
    echo "Thing ".$i." is ".$things[$i];
}

foreach ($things as $i=>$thing) {
    echo "Thing ".$i." is ".$thing;
}
buræquete
  • 12,943
  • 4
  • 34
  • 69
Trev
  • 125
  • 1
  • 2
8

I think best option is like same:

foreach ($lists as $key=>$value) {
    echo $key+1;
}

it is easy and normally

buræquete
  • 12,943
  • 4
  • 34
  • 69
Mikel Williams
  • 417
  • 5
  • 20
5

Jonathan is correct. PHP arrays act as a map table mapping keys to values. in some cases you can get an index if your array is defined, such as

$var = array(2,5);

for ($i = 0; $i < count($var); $i++) {
    echo $var[$i]."\n";
}

your output will be

2
5

in which case each element in the array has a knowable index, but if you then do something like the following

$var = array_push($var,10);

for ($i = 0; $i < count($var); $i++) {
    echo $var[$i]."\n";
}

you get no output. This happens because arrays in PHP are not linear structures like they are in most languages. They are more like hash tables that may or may not have keys for all stored values. Hence foreach doesn't use indexes to crawl over them because they only have an index if the array is defined. If you need to have an index, make sure your arrays are fully defined before crawling over them, and use a for loop.

The Brawny Man
  • 651
  • 6
  • 10
  • Yes, this is why in PHP we must "join arrays" by *keys* and not by *indexes*... See also [array_map](http://php.net/manual/en/function.array-map.php)(func,$a,$b). – Peter Krauss May 21 '13 at 11:51
  • Ops, dear reader and @TheBrawnyMan, remember also that your example is like a [array_push()](http://php.net/manual/en/function.array-push.php) bug (!). The recomendation is to use `$var[] = 10;` (see PHP link to guide), so the second `for` loop outputs the expected results. – Peter Krauss May 21 '13 at 12:29
5

PHP arrays have internal pointers, so try this:

foreach($array as $key => $value){
   $index = current($array);
}

Works okay for me (only very preliminarily tested though).

sth
  • 200,334
  • 49
  • 262
  • 354
1

I normally do this when working with associative arrays:

foreach ($assoc_array as $key => $value) {
 //do something
}

This will work fine with non-associative arrays too. $key will be the index value. If you prefer, you can do this too:

foreach ($array as $indx => $value) {
  //do something
}
buræquete
  • 12,943
  • 4
  • 34
  • 69
Randy Greencorn
  • 3,554
  • 2
  • 20
  • 15
  • 4
    What's the 'alternative' for? You know this is the same, besides the variable names? So the last sentence and code block is unnecessary, I'd say - if it does anything it just confuses.. – Dennis98 Oct 28 '16 at 18:50
  • @Dennis98 The difference is that one of them has an associative array as an input and the other one has a numeric array. Although I guess it'd be better if the answer was a bit more verbose. – I_ATE_YOUR_WORK_FILES Jul 19 '18 at 13:25
1

I solved this way, when I had to use the foreach index and value in the same context:

$array = array('a', 'b', 'c');
foreach ($array as $letter=>$index) {

  echo $letter; //Here $letter content is the actual index
  echo $array[$letter]; // echoes the array value

}//foreach

0

I use ++$key instead of $key++ to start from 1. Normally it starts from 0.

@foreach ($quiz->questions as $key => $question)
 <h2> Question: {{++$key}}</h2>
 <p>{{$question->question}}</p>
@endforeach

Output:

Question: 1
......
Question:2
.....
.
.
.
jamiryo
  • 33
  • 8
-1
foreach(array_keys($array) as $key) {
//  do stuff
}
gdmanandamohon
  • 2,055
  • 18
  • 34
-1

I would like to add this, I used this in laravel to just index my table:

  • With $loop->index
  • I also preincrement it with ++$loop to start at 1

My Code:

@foreach($resultsPerCountry->first()->studies as $result)
  <tr>
    <td>{{ ++$loop->index}}</td>                                    
  </tr>
@endforeach
Taranis
  • 79
  • 8