zoukankan      html  css  js  c++  java
  • php迭代器:Iterator和IteratorAggregate

    使用迭代模式遍历所有的对象的时候,都必须实现Traversable(遍历)接口。但是Traversable是一个内部的类,只有用c语言编写的类才可以实现Traversable实现。如果我们在自定义的 类中实现它,会报错。那么我们要实现对象的遍历,就必须通过Iterator或者IteratorAggregate接口实现Traversable接口。

    一,首先说说Iterator接口

    它是在c语言中定义的,都是抽象方法,所以我们在实现接口的时候,就必须定义这些方法,代码如下:

    Iterator extends Traversable {
        /* 方法 */
        abstract public mixed current ( void )
        abstract public scalar key ( void )
        abstract public void next ( void )
        abstract public void rewind ( void )
        abstract public boolean valid ( void )
    }

    接着我们在PHP中实现接口Iterator,代码如下:

    //自定义类实现接口Iterator
    class myIterator implements Iterator {
        private $position = 0;
        private $array = array(
            "firstelement",
            "secondelement",
            "lastelement",
        );  
     
        public function __construct() {
            $this->position = 0;
        }
        //定义rewind()-将数组指针移动到数组的开头位置
        function rewind() {
            var_dump(__METHOD__);
            $this->position = 0;
        }
        //定义current()-返回当前的值
        function current() {
            var_dump(__METHOD__);
            return $this->array[$this->position];
        }
        //定义可以key()-返回当前的键值
        function key() {
            var_dump(__METHOD__);
            return $this->position;
        }
        //定义next()-将数组指针向前进一位指向下一个数组元素
        function next() {
            var_dump(__METHOD__);
            ++$this->position;
        }
        //定义valid()-确定当前元素是否存在,并且必须在next()和rewind()方法之后才可以调用
        function valid() {
            var_dump(__METHOD__);
            return isset($this->array[$this->position]);
        }
    }
     
    $it = new myIterator;
     
    foreach($it as $key => $value) {
        var_dump($key, $value);
        echo "
    ";
    }

    代码运行结果如下:

    大家可能不明白,为什么利用foreach()就可以循环打印出类的属性,程序执行的顺序看我的注释,再次提醒大家注意
    “定义valid()-确定当前元素是否存在,并且必须在next()和rewind()方法之后才可以调用”。


    string(18) "myIterator::rewind" ----------程序开始执行首先调用rewind()函数,将数组指针移到数组开头位置
    string(17) "myIterator::valid" ----------接着调用valid()当前元素是否存在,这个函数每次紧跟rewind()和next()函数被调用
    string(19) "myIterator::current" ----------调用current()获取当前的值
    string(15) "myIterator::key" ----------调用key()获取当前位置的键值
    int(0)
    string(12) "firstelement"

    string(16) "myIterator::next" ----------上一步获取当前位置,肯定要调用next(),获取下一个位置的指针,即指针向下移动
    string(17) "myIterator::valid" ----------判断当前元素是否存在
    string(19) "myIterator::current" ----------如果存在,获取当前元素
    string(15) "myIterator::key" ----------获取当前键值,为了下一步指针向前移动
    int(1)
    string(13) "secondelement"

    string(16) "myIterator::next" ---------指针指向下一个元素
    string(17) "myIterator::valid" ---------判断当前元素是否存在
    string(19) "myIterator::current" ---------元素存在,获取当前的元素
    string(15) "myIterator::key" ---------获取当前键值
    int(2)
    string(11) "lastelement"

    string(16) "myIterator::next" ---------指针指向下一个位置
    string(17) "myIterator::valid" ---------判断当前位置是否有值。如果有获取值,没有就结束遍历

    二 ,IteratorAggregate接口

    是用来将Iterator接口要求实现的5个方法委托给其他类(比如ArrayIterator)来实现


    (1) ArrayIterator接口:允许从PHP数组中创建一个迭代器。上面我们通过实现Iterator接口实现迭代器,但是ArrayIterator可以直接跳过,实现同样的功能。

    (2)当ArrayIterator迭代器和IteratorAggregate类一起使用的时候,直接免去Iterator创建方法的工作,所以在实现IteratorAggregate类中的方法getIterator时候,返回一个ArrayIterator接口就好。

    (3) IteratorAggregate的c语言实现代码:定义抽象方法getIterator,所以实现接口的时候,必须定义该方法

    IteratorAggregate extends Traversable { 
             /* 方法 */
        abstract public Traversable getIterator ( void )
    }
    class myData implements IteratorAggregate {
        public $property1 = "Public property one";
        public $property2 = "Public property two";
        public $property3 = "Public property three";
     
        public function __construct() {
            $this->property4 = "last property";
        }
        //定义方法----getIterator()---返回一个Iterator类的实例
        public function getIterator() {
            //ArrayIterator()接口可以创建一个Iterator实例
            return new ArrayIterator($this);
        }
    }
     
    $obj = new myData();
     
    foreach($obj as $key => $value) {
        var_dump($key, $value);
        echo "
    ";
    }

    运行如下:
    string(9) "property1"
    string(19) "Public property one"

    string(9) "property2"
    string(19) "Public property two"

    string(9) "property3"
    string(21) "Public property three"

    string(9) "property4"
    string(13) "last property"

     

  • 相关阅读:
    (3)梯度下降法Gradient Descent
    特征工程
    python小笔记
    衡量线性回归法的指标MSE, RMSE,MAE和R Square
    最小二乘法
    最优化原理,凸优化
    线性回归Linear regression
    机器学习流程
    数据归一化Feature Scaling
    kafka重新设置group的offset
  • 原文地址:https://www.cnblogs.com/tkzc2013/p/10574399.html
Copyright © 2011-2022 走看看