【问题标题】:Does Iterator work only with numeric arrays?Iterator 是否仅适用于数值数组?
【发布时间】:2021-12-18 17:25:52
【问题描述】:

我在 w3schools 看到了一个例子:

<?php
// Create an Iterator
class MyIterator implements Iterator {
  private $items = [];
  private $pointer = 0;

  public function __construct($items) {
    // array_values() makes sure that the keys are numbers
    $this->items = array_values($items);
  }

  public function current() {
    return $this->items[$this->pointer];
  }

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

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

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

  public function valid() {
    // count() indicates how many items are in the list
    return $this->pointer < count($this->items);
  }
}

// A function that uses iterables
function printIterable(iterable $myIterable) {
  foreach($myIterable as $item) {
    echo $item;
  }
}

// Use the iterator as an iterable
$iterator = new MyIterator(["a", "b", "c"]);
printIterable($iterator);
?>

如果当前方法是关联数组而不是数字,则可以循环数组。如果是,我该怎么做?示例我们可以这样做:

function printIterable(iterable $myIterable) {
  foreach($myIterable as $item => $value) {
    echo  "$item - $value";
  }
}

// Use the iterator as an iterable
$iterator = new MyIterator(["a"=>1, "b"=>2, "c"=>3]);
printIterable($iterator);

当我尝试时。它打印这个:0 - 11 - 22 - 3

【问题讨论】:

  • 输出看起来不错,你想要它是什么?不过,您可能希望在 printIterable() 中的每一行之后添加一个行分隔符,这样会更容易阅读:)。
  • @TorbjörnStabo 它正在将数组打印为数字并且它是关联的,是否可以打印为关联只想知道
  • 这就是我要说的:)。 $arr = ['name' =&gt; 'Eric']; foreach($arr as $k =&gt; $v) { echo "$k: $v\n"; } 查看php.net/next 的初学者,然后查看该页面上的“另请参阅”部分。
  • 我会把它留给内部 PHP 数组指针,然后使用我之前提到的数组函数。
  • "如果我没有将 array_values() 函数放在构造函数中,它不会打印数组,如果我把它打印为数字的关联数组“就像我之前说的,如果你将该array_values() 调用添加到构造函数没有 没有关联数组。 Array_values() 返回关联数组的数字“版本”,然后保存在 $this->items 中。

标签: php arrays oop iterator


【解决方案1】:

PHP 以相同的方式处理数字数组和关联数组,打印它们时没有区别,并且相同的代码适用于两者(好吧,除非开始添加花哨的功能......)

是的,可以打印关联数组。

问题在于您的代码通过将 $pointer 属性初始化为 0(即数值)来假设数据数组键是数字的。可以通过使用 PHP 数组的内部指针 ($this->items) 或保留数组键的显式列表来解决这个问题。

版本 1 PHP 具有遍历数组的函数,它们被命名为 next()、current()、key() 等,并在https://www.php.net/manual/en/ref.array.php 下列出。这样可以在没有显式指针的情况下遍历数组:

while(key($arr) !== null) {
  echo current($arr)."\n";
  next($arr);
}

如果https://www.php.net/manual/en/class.iterator.php 下指定的方法在您的类中实现(implements Iterator),则可以使用这些函数,如下所示:

class MyIterator implements Iterator {
  private $items = [];
  private $pointer = 0;

  public function __construct($items) {
    $this->items = $items;
  }

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

  public function key() {
    return key($this->items);
  }
  // ...

可以看出它或多或少地键入了两次相同的调用。但是,如果您有一个更复杂的 Iterable 并添加了其他代码片段,那么它可能会开始变得值得。

第 2 版 如果您不想依赖版本 1 中的函数,您仍然可以使用 $this->pointer,但您必须保留数组键的显式列表:

class MyIterator implements Iterator {
  private $items = [];
  private $keys = [];
  private $pointer = 0;

  public function __construct($items) {
    $this->items = array_values($items);
    $this->keys = array_keys($items);
  }

  public function current() {
    return $this->items[$this->keys[$this->pointer]];

    // Alternative version:
    return $this->items[$this->key()];
  }

  // Return the key of the current element
  public function key() {
    return $this->keys[$this->pointer];
  }

  // Step the array one element, and then return that value
  public function next() {
    // Check that we're not moving out of bounds, if so return null
    // and follow the next() spec.

    ++$this->pointer;
    return $this->items[$this->keys[$this->pointer]];
    
    // Alternative version:
    return $this->current();
  }
  // ...

可以看出,版本 2 创建了另一个数组“级别”来跟踪(如果应同时支持关联数组和数值数组)。但可以做到。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-10-24
    • 2011-11-08
    • 1970-01-01
    • 2014-01-13
    • 1970-01-01
    • 2021-12-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多