【问题标题】:preview next array element using foreach使用 foreach 预览下一个数组元素
【发布时间】:2016-04-22 01:31:47
【问题描述】:

我有一个 foreach 在数组中的项目之间迭代以构建一个 excel 文件。 如果数组中的下一个元素匹配特定条件(在一个键中具有特定值),我想在数组中的每个项目之后放置一个总行。 因此,我想使用next() 来检查该值,但据我所知,对于我使用 next 读取的 here,我会将指针移至下一行,答案是使用 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';
    }
}

但这不起作用。如何解决?

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

【问题讨论】:

  • 不确定,但=='4' 正在寻找一个字符串,而不是一个可能的整数==4
  • for($x = 0; $x
  • @Fred-ii- 实际上真正的代码正在寻找一个字符串(一些字母)。
  • si Lelio,感恩!钢琴...非速度马“不太破旧”;-)
  • 没有什么可以阻止您使用单独的数组迭代器,您可以在foreach 循环中以任何您希望的方式使用它。在foreach loop 之外做:$iter = new \ArrayIterator($cred)。在循环内部,确保 foreach 循环和 $iter 留在步骤中,即在循环结束时执行 next()。它有用的地方是你可以在 $iter 上随心所欲地做next()prev()foreach 不会知道或关心。

标签: php arrays foreach


【解决方案1】:

要求是:

  • 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';
    }
}

【讨论】:

    【解决方案2】:

    您可以在使用 next 后尝试使用 prev 功能。这可能不是最好的解决方案,但应该可以。

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

    应该输出 2,3

    编辑

    实际上 next() 在执行后不会影响您的循环键并为您提供正确的下一个值。在回答您提供的link 时也会注意到这一点。您也可以使用自定义迭代器和 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();
    }
    ?>
    

    【讨论】:

      【解决方案3】:

      如果当前项目具有您的特殊键/值对,我会检查每个循环,然后在最后再检查一次。这样您就不必访问下一项(并前后移动指针)。如果它比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 行为 4 作为键 'tipo' 的值,我想在当前行之后回显 'Total'
      • @LelioFaieta,我做了一个小的编辑。正确的是,当前项检查值 4,但在常规行输出之前,这意味着它发生在上一行之后。
      • 结果应该是 1 Total, 2 Total, 3 4 Total, 5 Total。它应该跳过总计 3,因为下一项是 4
      • 我现在在“编辑”中更改了它。使用for 循环很可能会更优雅一些,但我保留了foreach 只是为了演示一个可能的解决方案。
      【解决方案4】:

      试试这个代码

      $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 )
          {
              //
          }
      }
      

      【讨论】:

      • 谢谢!这是一个有效的解决方法,但我希望了解如何在不移动 foreach 循环中的指针的情况下预览数组中的下一项。
      • $next = $creds[next($keys)] 下一个值
      猜你喜欢
      • 2012-01-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多