【问题标题】:Next Iterator method for associative ArrayNext 关联数组的迭代器方法
【发布时间】:2012-06-19 22:38:51
【问题描述】:

我想在 PHP 迭代器中使用关联数组:

http://php.net/manual/en/class.iterator.php

有可能吗?

我定义了这些方法:

  public function rewind(){    
    reset($this->_arr);
    $this->_position = key($this->_arr);
  }

  public function current(){    
    return $this->_arr[$this->_position];
  }

  public function key(){
    return $this->_position;
  }

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

  public function valid(){    
    return isset($this->_arr[$this->_position]);
  }

问题是它没有正确迭代。我只得到一个元素。

我认为这是因为 next() 方法中的 ++$this->_position 代码没有任何效果,因为 _position 是一个字符串(关联数组的键)。

那么我怎样才能转到这种类型数组的下一个元素呢?

【问题讨论】:

  • 出于好奇,您为什么不直接使用ArrayIterator
  • 你能显示更多你的代码吗?那将是 a) 你说class XYZ implements Iterator b) 你(尝试)使用它的部分。
  • “我定义了这些方法”——它被称为“从文档中按原样复制粘贴”;-)
  • 如果这是一个持有数组的类,考虑实现IteratorAggregate并在getIterator中为该数组返回一个ArrayIterator

标签: php arrays iterator


【解决方案1】:

http://ideone.com/Fxt0j

class myIterator implements Iterator {
    private $position = 0;
    private $keys;

    public function __construct(array $arr) {
        $this->array = $arr;
        $this->keys = array_keys($arr);
        $this->position = 0;
    }

    function rewind() {
        $this->position = 0;
    }

    function current() {
        return $this->array[$this->key()];
    }

    function key() {
        return $this->keys[$this->position];
    }

    function next() {
        ++$this->position;
    }

    function valid() {
        return isset($this->keys[$this->position]);
    }
}

$it = new myIterator(array(
        'a' => "firstelement",
        'b' => "secondelement",
        'c' => "lastelement",
    ));

foreach($it as $key => $value) {
    var_dump($key, $value);
    echo "\n";
}

【讨论】:

  • 如果注释和解释此代码将更加有用,因此除了 OP 之外的其他人也可以从您的知识中受益。
  • 我真的,真的不明白为什么还要重新发明轮子...使用从 ArrayObject 得到的 ArrayIterator 将关联数组转换为简单得多...而且不需要写下我们的自己的 ArrayIterator...
  • 这只是php.net例子的一个副本
  • 在查看了 php.net 示例后,我从 google 来到了这个页面。问题是把一些不是你写的东西归功于自己。我建议提及来源,这样就可以了。评论的年龄 - IMO - 无关紧要,有用的信息总是有用的。如果您不希望人们对您的旧帖子发表评论,那么,我不知道,请删除它。
  • php.net/manual/en/class.iterator.php - 示例 #1 基本用法。对不起,如果我让你不高兴。为什么你一直说 2 年,有那么重要吗?
【解决方案2】:
function rewind() {
    reset($this->_arr);
}

function current() {
    return current($this->_arr);
}

function key() {
    return key($this->_arr);
}

function next() {
    next($this->_arr);
}

function valid() {
    return key($this->_arr) !== null;
}

【讨论】:

  • foreach 循环中,我假设这不会返回键 - 仅返回数字表示。对吗?
  • @OGHaza 谢谢。我认为他的最新编辑对我来说还可以吗?我的原始代码没有错误,但我认为我更喜欢他的最新编辑。
  • 优秀的解决方案。还请添加常规中使用的计数和其他功能
【解决方案3】:

为什么不从您的关联 Array 创建一个 ArrayObject?然后你可以从这个ArrayObjectgetIterator() 并根据需要调用key()next() 等...

一些例子:

$array = array('one' => 'ONE', 'two' => 'TWO', 'three' = 'THREE');
// create ArrayObject and get it's iterator
$ao = new ArrayObject($my_array);
$it = $ao->getIterator();
// looping
while($it->valid()) {
    echo "Under key {$it->key()} is value {$it->current()}";
    $it->next();
}

ArrayObject
ArrayIterator

【讨论】:

    【解决方案4】:
    class MyItrator implements Iterator 
    {
        private $_arr;
    
        public function __construct(array $arr) 
        {
            $this->_arr = $arr;
        }
    
    
        public function rewind()
        {
            reset($this->_arr);
        }
    
        public function current()
        {
            return current($this->_arr);
        }
    
        public function key()
        {
            return key($this->_arr);
        }
    
        public function next()
        {
            next($this->_arr);
        }
    
        public function valid()
        {
            return isset($this->_arr[key($this->_arr)]);
        }
    }
    

    【讨论】:

      【解决方案5】:

      我知道这是一个老问题,但它可以很简单

      public function current()
      {
          return $this->array[array_keys($this->array)[$this->position]];
      }
      
      public function next()
      {
          ++$this->position;
      }
      
      public function key()
      {
          return array_keys($this->array)[$this->position];
      }
      
      public function valid()
      {
          return array_key_exists($this->position, array_keys($this->array)[$this->position]);
      }
      
      public function rewind()
      {
          $this->position = 0;
      }
      

      我知道@zerkms 发布了一个类似的答案,但恕我直言,如果对象已经构建并且您具有扩展数组的功能,那么这不起作用

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-05-20
        • 2021-11-01
        • 1970-01-01
        • 2013-12-17
        • 1970-01-01
        • 2020-04-17
        • 1970-01-01
        相关资源
        最近更新 更多