Does PHP Have a "built-in" iterator in a Foreach loop?
Asked Answered
H

8

15

I'm using a foreach loop to go through the REQUEST array, as I want to have an easy way to utilize the REQUEST array's keys and values.

However, I also want to have a numerical index of how many times the loop has run, as I'm writing a spreadsheet with PHPExcel, and I want to use the SetCellValue function. I'm thinking something like this:

foreach( $_REQUEST as $key => $value){
    $prettyKeys = ucwords(preg_replace($patt_underscore," ",preg_replace($patt_CC,"_",$key)));
    $prettyVals = ucwords(preg_replace($patt_underscore," ",preg_replace($patt_CC,"_",$value)));
    // Replace CamelCase with Underscores, then replace the underscores with spaces and then capitalize string
    // "example_badUsageOfWhatever" ==> "Example Bad Usage Of Whatever"


    $myExcelSheet->getActiveSheet()->SetCellValue( "A". $built-in-foreach-loop-numerical-index ,$prettyKeys);
    $myExcelSheet->getActiveSheet()->SetCellValue( "B". $built-in-foreach-loop-numerical-index ,$prettyVals);
}

I know I can easily implement something like $c = 0 outsite the foreach and then just increment it each time the loop is run, but is there something cleaner?

Harneen answered 13/8, 2012 at 14:36 Comment(2)
In a word, no. As in pretty much any language, if you want a counter you have to implement it yourself.Lyford
Use for loop if you need this functionality.Centimeter
G
7

PHP's foreach does not have this functionality built in (per the manual). Use a for loop to have an iterator or implement it yourself.

Ganoid answered 13/8, 2012 at 14:39 Comment(0)
O
5

The for loop will give you an automatic counter, but no way to cycle through your $_REQUEST associative array. The foreach loop will let you cycle through, but without a built-in counter. It's a tradeoff, but at least it's a very manageable one (only takes 2 lines of code to build the counter)!

Orangy answered 13/8, 2012 at 14:39 Comment(0)
S
2

No, there is no built-in iterator numerical index. You can solve this problem in other ways, though.

The most obvious way to do this is using a simple for loop:

for ($i = 0, $numFoo = count($foo); $i < $numFoo; ++$i) {
    // ...
}

You can also use foreach with a counter variable:

$i = 0;
foreach ($foo as $key => $value) {
    // ...
    ++$i;
}
Salubrious answered 13/8, 2012 at 15:22 Comment(0)
M
1

Use the SPL Iterator Class. I'm sure there is something in there you can utilize for this.

Morganatic answered 13/8, 2012 at 14:48 Comment(2)
Do you know of any good resources for learning how to use these? I've never seen that facet of PHP.Harneen
I never found any, I've used IteratorIterator, LimitIterator and just had to figure it out myself. Go Google crazy, I'm sure it's out thereMorganatic
A
1

Using a For-Loop

You definitely can do this with a for-loop, it's just a bit ugly:

reset($array);
for ($i=0; $i<count($array); $i++) {
    // $i is your counter
    // Extract current key and value
    list($key, $value) = array(key($array), current($array));

    // ...body of the loop...

    // Move to the next array element
    next($array);
}

Extend ArrayIterator

My preferred way would be to extend ArrayIterator. Add an internal counter, then override next() and rewind() to update the counter. The counter gives the 0-based key of the current array element:

class MyArrayIterator extends ArrayIterator
{
    private $numericKey = 0;

    public function getNumericKey()
    {
        return $this->numericKey;
    }

    public function next()
    {
        $this->numericKey++;
        parent::next();
    }

    public function rewind()
    {
        $this->numericKey = 0;
        parent::rewind();
    }
}

// Example:
$it = new MyArrayIterator(array(
    'string key' =>'string value',
    1 =>'Numeric key value',
));
echo '<pre>';
foreach ($it as $key =>$value) {
    print_r(array(
        'numericKey' =>$it->getNumericKey(),
        'key' =>$key,
        'value' =>$value,
    ));
}

// Output:
// Array
// (
//     [numericKey] => 0
//     [key] => string key
//     [value] => string value
// )
// Array
// (
//     [numericKey] => 1
//     [key] => 1
//     [value] => Numeric key value
// )
Alta answered 28/7, 2013 at 18:29 Comment(0)
B
0

Your question is answered also here: How can I find out how many times a foreach construct loops in PHP, without using a "counter" variable?

Shortly, no. There isn't any easier way.

Breath answered 13/8, 2012 at 14:45 Comment(0)
S
0

You can get the index of each key of $_REQUEST array:

$req_index= array_flip (array_keys($_REQUEST));

Now you have the numerical index of the current element through $req_index[$key], which gives also the number of iterations of the loop:

foreach($_REQUEST as $key => $value){
    $prettyKeys = ucwords(preg_replace($patt_underscore," ",preg_replace($patt_CC,"_",$key)));
    $prettyVals = ucwords(preg_replace($patt_underscore," ",preg_replace($patt_CC,"_",$value)));
    // Replace CamelCase with Underscores, then replace the underscores with spaces and then capitalize string
    // "example_badUsageOfWhatever" ==> "Example Bad Usage Of Whatever"

    //THE NUMERICAL INDEX IS $req_index[$key]
    $myExcelSheet->getActiveSheet()->SetCellValue( "A". $req_index[$key], $prettyKeys);
    $myExcelSheet->getActiveSheet()->SetCellValue( "B". $req_index[$key], $prettyVals);
}
Serpent answered 12/5, 2014 at 15:6 Comment(0)
L
0

You can actually use foreach with combination of array_values() which will give you keys for each element in the array.

For Example:

$colors = ["red", "blue", "green"];

foreach(array_values($colors) as $key => $color) {
    echo "$color $key";
}
/**Output:
red 0
blue 1
green 2*/
Longplaying answered 30/8, 2023 at 11:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.