Есть ли у PHP встроенный итератор в цикле Foreach?

Я использую цикл foreach для прохождения массива REQUEST, так как я хочу иметь простой способ использования ключей и значений массива REQUEST.

Тем не менее, я также хочу иметь числовой указатель того, сколько раз цикл работал, поскольку я пишу таблицу с PHPExcel, и я хочу использовать функцию SetCellValue. Я думаю примерно так:

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);
}

Я знаю, что могу легко реализовать что-то вроде $c = 0 outsite foreach, а затем просто увеличивать его каждый раз, когда цикл запускается, но есть ли что-то более чистое?

Ответ 1

PHP foreach не имеет встроенных функций (в руководстве). Используйте для цикла, чтобы иметь итератор или реализовать его самостоятельно.

Ответ 2

Цикл for даст вам автоматический счетчик, но не будет проходить цикл через ваш ассоциативный массив $_REQUEST. Цикл foreach позволит вам циклически перемещаться, но без встроенного счетчика. Это компромисс, но по крайней мере он очень управляемый (требуется только 2 строки кода для создания счетчика)!

Ответ 3

Используйте класс итератора SPL. Я уверен, что там есть что-то, что можно использовать для этого.

Ответ 4

Нет, нет встроенного числового индекса итератора. Вы можете решить эту проблему иными способами.

Самый очевидный способ сделать это - использовать простой цикл for:

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

Вы также можете использовать foreach с переменной счетчика:

$i = 0;
foreach ($foo as $key => $value) {
    // ...
    ++$i;
}

Ответ 5

Использование For-Loop

Вы определенно можете сделать это с помощью цикла for, это просто немного уродливо:

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);
}

Расширить ArrayIterator

Мой предпочтительный способ - расширить ArrayIterator. Добавьте внутренний счетчик, затем переопределите next() и перемотайте(), чтобы обновить счетчик. Счетчик дает ключ на основе 0 текущего элемента массива:

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
// )

Ответ 7

Вы можете получить индекс каждого ключа массива $_REQUEST:

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

Теперь у вас есть числовой индекс текущего элемента через $req_index[$key], который также дает число итераций цикла:

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);
}