使用 foreach 预览下一个数组元素


preview next array element using foreach

我有一个foreach,它在数组中的项目之间迭代以构建excel文件。如果数组中的下一个元素与特定条件匹配(在一个键中具有特定值),我想在数组中的每个项目之后放置一个总计行。所以我想使用 next() 来检查该值,但据我所知,对于我在这里阅读的内容,接下来我将指针移动到下一行,答案是使用 current。如何在不移动指针的情况下查看数组中的下一项?读到这个问题,我写了这篇文章:

foreach($creds as $cred){
    echo $cred['tipo'];
    //if the next item has a 'tipo' key with a specific value
    if(current($creds['tipo'])!='4'){
        echo 'Total';
    }
}

但这行不通。如何解决?

编辑:根据答案,我将在下一次迭代的开始时移动回声"总计"内容,而不是当前迭代的底部。据我在答案中看到,没有其他使用 foreach 的解决方案

要求是:

  • foreach 循环内查看next值或键,但不更改foreach循环的current迭代器指针的位置。

虽然它是更多的代码,但一种方法是在同一数组上创建一个完全独立的迭代器。

这个新iterator必须与foreach循环保持同步,但这很简单。

优点是你可以使用next()prev()current()等来操纵任何你想要的方式,并且知道foreach循环不会受到影响。

对于此示例,要求在当前条目之前测试下一个条目。从指向第二个条目的迭代器开始,每次都前进是值得的。

例如,未经测试的代码...

$iter = new 'ArrayIterator($cred)s; // mirror of the `foreach` loop 

迭 代 foreach($creds as $cred) {

    // get next key and value...
    $iter->next(); 
    $nextKey = $iter->key();
    $nextValue = $iter->current();
    echo $cred['tipo'];
    // if the next item has a 'tipo' key with a specific value
    if($nextValue['tipo']) != '4'){
        echo 'Total';
    }
}

试试这段代码

$keys = array_keys($creds);
for($i = 0; $i < sizeof($keys); $i++)
{
    echo $creds[$keys[$i]] .' ';
    //$creds[$keys[$i+1]] - next item
    if($keys[$i+1] == 'tipo' && $creds[$keys[$i+1]] == 4 )
    {
        //
    }
}

我会在每个循环中检查当前项目是否具有您的特殊键/值对,然后在最后再检查一次。这样,您就不必访问下一项(并前后移动指针)。如果它比echo 'Total';复杂,那么你可以把它包装到一个函数中,以避免在foreach循环中和之后重复代码。

$creds = [
    ['tipo' => '1'],
    ['tipo' => '2'],
    ['tipo' => '3'],
    ['tipo' => '4'],
    ['tipo' => '5'],
];
foreach ($creds as $cred) {
    if ($cred['tipo'] == '4') {
        echo "Total'n";
    }
    echo $cred['tipo'] . "'n";
}
// If the very last row had the special key, print the sum one more time
if ($cred['tipo'] == '4') {
    echo "Total'n";
}

/* Output:
1
2
3
Total
4
5
*/

编辑:

我误解了您的要求("如果数组中的下一个元素与特定条件匹配,我想在数组中的每个项目之后放置一个总计行")。如果你想要相反的方式,我建议,在变量$previous_row中"缓冲"当前行的值,直到foreach循环向前移动指针并且你能够访问和检查值:

$creds = [
    ['tipo' => '1'],
    ['tipo' => '2'],
    ['tipo' => '3'],
    ['tipo' => '4'],
    ['tipo' => '5'],
];
$previous_row = '';
foreach ($creds as $cred) {
    echo $previous_row;
    if ($previous_row && $cred['tipo'] != '4') {
        echo "Total'n";
    }
    $previous_row = $cred['tipo'] . "'n";
}
// If the very last row had the special key, print the sum one more time
echo $previous_row;
if ($cred['tipo'] != '4') {
    echo "Total'n";
}

/* Output:
1
Total
2
Total
3
4
Total
5
Total
*/

使用next后,您可以尝试使用prev函数。这可能不是最好的解决方案,但它应该有效。

$values = array(1,2,3);
foreach ($values as $a) {
    print next($values);
    prev();
}

应输出 2,3

编辑

实际上 next() 在执行后不会影响您的循环键,并为您提供下一个值。在回答您提供的链接时也注意到了这一点。您还可以使用自定义迭代器和 prev 函数手动更改迭代。http://php.net/manual/en/language.oop5.iterations.php

<?php
class MyIterator implements Iterator
{
    private $var = array();
    public function __construct($array)
    {
       if (is_array($array)) {
            $this->var = $array;
    }
}
public function rewind()
{
    reset($this->var);
}
public function current()
{
    $var = current($this->var);
    return $var;
}
public function key() 
{
    $var = key($this->var);
    return $var;
}
public function next() 
{
    $var = next($this->var);
    return $var;
}
public function prev()
{
    $var = prev($this->var);
    return $var;
}
public function valid()
{
    $key = key($this->var);
    $var = ($key !== NULL && $key !== FALSE);
    return $var;
}
}
$values = array(1,2,3);
$it = new MyIterator($values);
foreach ($it as $a => $b) {
   print 'next is '.$it->next();
   $it->prev();
}
?>