PHP foreach遍历多维数组实现方式


Posted in PHP onNovember 16, 2016

介绍
正常我们的foreach可以按顺序把一维数组里面每个 key => value 打印出来,但是如果是多维数组则需要循环在嵌套循环,或则递归实现,但是这些方式都不够灵活,因为在不确定该数组是几维的情况下,不可能永无止境的嵌套循环,如果采用递归到可以解决,但是如果只想使用foreach全部循环出来该如何实现?

实现方式 一
采用PHP本身自带的迭代器类 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
 */

实现方式 二
自己实现一个类似于 RecursiveIteratorIterator 的迭代器类,实现多维数组横向打印功能

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

内部执行方式

1、foreach 循环我们自定义的foreachPrintfArr类,会自动调用内部这5个方法 valid()、rewind()、key()、next()、current() 我们只需要实现这几个方法即可.

2、调用顺序:
第1次 => rewind -> valid -> current -> key
第2次~n次 =>  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
   */

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

PHP 相关文章推荐
PHP的面试题集
Nov 19 PHP
谷歌音乐搜索栏的提示功能php修正代码
May 09 PHP
php中获得视频时间总长度的另一种方法
Sep 15 PHP
php 中的4种标记风格介绍
May 10 PHP
php实现执行某一操作时弹出确认、取消对话框
Dec 30 PHP
PHP判断是否有Get参数的方法
May 05 PHP
php简单计算页面加载时间的方法
Jun 19 PHP
PHP连接Nginx服务器并解析Nginx日志的方法
Aug 16 PHP
教大家制作简单的php日历
Nov 17 PHP
php中preg_replace_callback函数简单用法示例
Jul 21 PHP
php中使用websocket详解
Sep 23 PHP
PHP实现的解汉诺塔问题算法示例
Aug 06 PHP
php数据库操作model类(使用__call方法)
Nov 16 #PHP
php实现的简单数据库操作Model类
Nov 16 #PHP
iOS自定义提示弹出框实现类似UIAlertView的效果
Nov 16 #PHP
PHP中串行化用法示例
Nov 16 #PHP
PHP单态模式简单用法示例
Nov 16 #PHP
php实现替换手机号中间数字为*号及隐藏IP最后几位的方法
Nov 16 #PHP
php实现当前页面点击下载文件的实例代码
Nov 16 #PHP
You might like
php递归方法实现无限分类实例代码
2014/02/28 PHP
phpStudy访问速度慢和启动失败的解决办法
2015/11/19 PHP
PHP扩展Swoole实现实时异步任务队列示例
2019/04/13 PHP
laravel框架模板之公共模板、继承、包含实现方法分析
2019/08/30 PHP
extjs 为某个事件设置拦截器
2010/01/15 Javascript
js 图片等比例缩放代码
2010/05/13 Javascript
你必须知道的Javascript知识点之"字面量和对应类型"说明介绍
2013/04/23 Javascript
鼠标焦点离开文本框时验证的js代码
2013/07/19 Javascript
javascript中expression的用法整理
2014/05/13 Javascript
详解JavaScript中shift()方法的使用
2015/06/09 Javascript
浅谈Nodejs观察者模式
2015/10/13 NodeJs
全面解析Bootstrap中transition、affix的使用方法
2016/05/30 Javascript
js判断浏览器是否支持严格模式的方法
2016/10/04 Javascript
微信小程序 MINA文件结构
2016/10/17 Javascript
javascript实现文字无缝滚动
2016/12/27 Javascript
小程序getLocation需要在app.json中声明permission字段
2019/04/04 Javascript
jquery实现的分页显示功能示例
2019/08/23 jQuery
webpack是如何实现模块化加载的方法
2019/11/06 Javascript
Openlayers显示地理位置坐标的方法
2020/09/28 Javascript
Python使用struct处理二进制的实例详解
2017/09/11 Python
Python 使用PIL中的resize进行缩放的实例讲解
2018/08/03 Python
Python二维数组实现求出3*3矩阵对角线元素的和示例
2019/11/29 Python
Python处理mysql特殊字符的问题
2020/03/02 Python
python使用PIL剪切和拼接图片
2020/03/23 Python
python rsa-oaep加密的示例代码
2020/09/23 Python
西班牙汉普顿小姐:购买帆布鞋和太阳镜
2016/10/23 全球购物
Shopping happy life西班牙:以最优惠的价格提供最好的时尚配饰
2020/03/13 全球购物
美国球迷装备的第一来源:FOCO
2020/07/03 全球购物
奥地利手表、香水、化妆品和珠宝购物网站:Brasty.at
2021/01/17 全球购物
高中毕业生自我鉴定范文
2013/09/26 职场文书
商务英语本科生的自我评价分享
2013/11/15 职场文书
党员批评与自我批评总结
2014/10/15 职场文书
公司离职证明范本
2014/10/17 职场文书
Python 中 Shutil 模块详情
2021/11/11 Python
Python Django项目和应用的创建详解
2021/11/27 Python
Elasticsearch Recovery 详细介绍
2022/04/19 Java/Android