混合对象/数组迭代

时间:2014-05-13 08:06:59

标签: php object iterator

我需要一种迭代任何数组或对象的方法($ this-> _data)。

目前的草案如下:

class values implements \Iterator{
    private $_data = null; // array or object
    private $_keys = [];
    private $_key = false;
    // ------------ \Iterator implementation
    public function current(){
        return $this->get($this->_key);
    }
    public function key(){
        return $this->_key;
    }
    public function next(){
        $this->_key = \next($this->_keys);
    }
    public function rewind(){
        $this->_keys = [];
        foreach ($this->_data as $k => $v){
            $this->_keys[] = $k;
        }
        $this->_key = \reset($this->_keys);
    }
    public function valid(){
        if (false === $this->_key){
            return false;
        }
        return $this->has($this->_key);
    }
}

问题是我不想为密钥保留额外的数组。

可能有更好的方法来迭代对象的键,避免为此目的创建额外的abject /数组吗?

(外部迭代器不是一个选项,因为我不希望在foreach循环中创建额外的对象)

与本机myClass :: methods和包装器的值:: methods

混合使用的示例
class myClass{
    var $x = 'x';
    var $y = 'y';
    public function hello(){
        echo 'Hello, '.$this->x;
    }
}
$a = new myClass();
$values = new values($a);
foreach ($values as $k => $v){
   $values[$k] = $v.' modified';
}
$a->hello();

附加说明:

  • 可以重复使用值实例(通过替换$ this-> _data)
  • 此类的使用可能非常密集(从100到超过100000个不同的对象/数组通过)
  • 值可以在值包装器之外使用和/或更改(参见上面的示例)

2 个答案:

答案 0 :(得分:0)

虽然您可以自己实现Iterator,但不需要单独存储$keys(我可以根据需要显示),您可以使用或扩展该类ArrayObject。它看起来完全符合您的需求。

检查此示例:

$a = new ArrayObject(array(
    'a' => 'foo',
    'b' => 'bar'
));

foreach($a as $k => $v) {
    var_dump($k, $v);
}

输出:

string(1) "a"
string(3) "foo"
string(1) "b"
string(3) "bar"

答案 1 :(得分:0)

对于PHP 5.5.0 +

嗯,实际上它失败了,因为它会在每次调用时创建Generator实例

class values implements IteratorAggregate{
    private $_data = null; // array or object
    public function __construct($data = null){
        $this->_data = $data;
    }
    private static function g($data){
        foreach ($data as $k => $v){
                yield $k => $v;
        }
    }
    public function getIterator(){
        return self::g($this->_data);
    }
}

希望php 5.4的替代方案