问题 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 在foreach外面,然后每次循环运行时只增加它,但是有更清洁的东西吗?


12448
2017-08-13 14:36


起源

总之,没有。就像几乎所有语言一样,如果你想要一个计数器,你必须自己实现它。 - DaveRandom
使用 for 循环,如果你需要这个功能。 - Tim


答案:


PHP的foreach没有内置的这个功能(根据手册)。用一个 for循环 有一个迭代器或自己实现它。


5
2017-08-13 14:39





for 循环会给你一个自动计数器,但没有办法循环你的 $_REQUEST 关联数组。该 foreach 循环将让你循环,但没有内置计数器。这是一个权衡,但至少它是一个非常易于管理的(只需要2行代码来构建计数器)!


5
2017-08-13 14:39





使用 SPL迭代器类。我相信你可以利用这些东西。


1
2017-08-13 14:48



你知道学习如何使用它们的任何好资源吗?我从未见过PHP的那个方面。 - Goldentoa11
我从来没有找到任何东西,我使用过IteratorIterator,LimitIterator,只是不得不自己搞清楚。谷歌疯了,我敢肯定它在那里 - wesside


不,没有内置的迭代器数字索引。但是,您可以通过其他方式解决此问题。

最明显的方法是使用简单的方法 for 循环:

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

你也可以使用 foreach 带有计数器变量:

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

1
2017-08-13 15:22





使用For循环

你肯定可以用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()和rewind()以更新计数器。计数器给出当前数组元素的从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
// )

1
2017-07-28 18:29





您的问题也在这里得到解答: 如何在不使用“计数器”变量的情况下找出foreach构造在PHP中循环的次数? 

不久,没有。没有更简单的方法。


0
2017-08-13 14:45





您可以获取$ _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);
}

0
2018-05-12 15:06