Home  >  Article  >  Backend Development  >  PHP foreach implements traversal of multi-dimensional arrays

PHP foreach implements traversal of multi-dimensional arrays

墨辰丷
墨辰丷Original
2018-05-30 17:21:522493browse

This article mainly introduces in detail the implementation of PHP foreach traversing multi-dimensional arrays. It has certain reference value. Interested friends can refer to it

Introduction
Normally our foreach can print out each key => value in the one-dimensional array in order, but if it is a multi-dimensional array, it needs to loop in a nested loop, or implement it recursively, but these methods are not flexible enough, because in When you are not sure how many dimensions the array has, it is impossible to have an endless nested loop. If you use recursion, it can be solved. But if you just want to use foreach to loop out all the loops, how to implement it?

Implementation method one
Use PHP’s own iterator class RecursiveIteratorIterator

  $test_arr = array(1,2,3,array(4,'aa'=>5,6,array(7,'bb'=>8),9,10),11,12); 
  $arrayiter = new RecursiveArrayIterator($test_arr);
  $iteriter = new RecursiveIteratorIterator($arrayiter);
  //直接打印即可按照横向顺序打印出来
  foreach ($iteriter as $key => $val){ 
    echo $key.'=>'.$val; 
  } 
  //结果
  /* 
    0=>1
    1=>2 
    2=>3
    0=>4
    aa=>5
    2=>6
    0=>7
    bb=>8
    4=>9
    5=>10
    4=>11
    5=>12
 */

Implementation method two
Implement an iterator class similar to RecursiveIteratorIterator to realize the horizontal printing function of multi-dimensional array

class foreachPrintfArr implements Iterator {
    //当前数组作用域
    private $_items; 
    private $_old_items;
    //保存每次执行数组环境栈
    private $_stack = array(); 

    public function __construct($data=array()){
      $this->_items = $data;
    }

    private function _isset(){
      $val = current($this->_items);

      if (empty($this->_stack) && !$val) {
        return false;
      } else {
        return true;
      }  
    }

    public function current() {
      $this->_old_items = null;
      $val = current($this->_items);

      //如果是数组则保存当前执行环境,然后切换到新的数组执行环境
      if (is_array($val)){
        array_push($this->_stack,$this->_items);
        $this->_items = $val;
        return $this->current();
      }

      //判断当前执行完成后是否需要切回上次执行环境
      //(1) 如果存在跳出继续执行
      //(2) 如果不存在且环境栈为空,则表示当前执行到最后一个元素
      //(3) 如果当前数组环境下一个元素不存在,则保存一下当前执行数组环境 $this->_old_items = $this->_items;
      //然后切换上次执行环境 $this->_items = array_pop($this->_stack) 继续循环, 直到当前数组环境下一个
      //元素不为空为止
      while (1) {
        if (next($this->_items)) {  
          prev($this->_items); break;
        } elseif (empty($this->_stack)) {
          end($this->_items); break;
        } else {
          end($this->_items);
          if (!$this->_old_items) 
            $this->_old_items = $this->_items;
          $this->_items = array_pop($this->_stack);
        }
      }

      return $val;
    }

    public function next() {
      next($this->_items);  
    }

    public function key() {
      // 由于 key() 函数执行在 current() 函数之后
      // 所以在 current() 函数切换执行环境 , 会导致切换之前的执行环境最后一个 key
      // 变成切换之后的key , 所以 $this->_old_items 保存一下切换之前的执行环境
      // 防止key打印出错
      return $this->_old_items ? key($this->_old_items) : key($this->_items);
    }

    public function rewind() {
      reset($this->_items);
    }

    public function valid() {                                       
      return $this->_isset();
    }
  }

Internal execution method

##1. Foreach loops our custom foreachPrintfArr class, which will automatically call the five internal methods valid(), rewind( ), key(), next(), current() We only need to implement these methods.

2. Calling sequence:

1st time => rewind -> valid - > current -> key
2nd~nth time=> next -> valid -> current -> key

   $test_arr = array(1,2,3,array(4,'aa'=>5,6,array(7,'bb'=>8),9,10),11,12);
   $iteriter = new foreachPrintfArr($test_arr);
   foreach ($iteriter as $key => $val){
     echo $key.'=>'.$val;
   } 
   //结果:
   /* 
   0=>1
   1=>2
   2=>3
   0=>4
   aa=>5
   2=>6
   0=>7
   bb=>8
   4=>9
   5=>10
   4=>11
   5=>12
   */

The above is the entire content of this article, I hope it will be helpful to everyone’s study.


Related recommendations:

Tutorial details on how to achieve multiple inheritance effects through PHP interface multiple inheritance and tarits

PHP How to get the start date and end date of the week of a certain year tutorial

phpString reversal is often used in interviews Problems encountered

The above is the detailed content of PHP foreach implements traversal of multi-dimensional arrays. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn