【问题标题】:iterator_to_arrayiterator_to_array
【发布时间】:2010-11-28 11:10:03
【问题描述】:

DatePeriod 是一个用于处理重复日期的 PHP 类。它的方法数量非常有限。因此,当我想使用重复日期执行基本数组函数时,我必须将其复制到带有iterator_to_array 的数组中。奇怪的是,复制它似乎会破坏它。任何想法为什么?

$p=new DatePeriod(date_create('2008-01-01'),
                  DateInterval::createFromDateString( "+2 days" ),
                  date_create('2008-12-31')); 

echo count(iterator_to_array($p)); //183 

$a=iterator_to_array($p); 
echo count($a); //0 

【问题讨论】:

  • 很抱歉撞了一个两年前的帖子,但您找到原因了吗?

标签: php oop iterator spl


【解决方案1】:

这就是我要做的。我会扩展DatePeriod 并实现toArray 方法:

class MyDatePeriod extends DatePeriod
{
    public $dates;

    public function toArray()
    {
        if ($this->dates === null) {
            $this->dates = iterator_to_array($this);
        }

        return $this->dates;
    }
}

$p = new MyDatePeriod(date_create('2008-01-01'),
                      DateInterval::createFromDateString( "+2 days" ),
                      date_create('2008-12-31'));

echo count($p->toArray()) . "\n"; // 183

echo count($p->toArray()) . "\n"; // 183

【讨论】:

  • 我不明白为什么类内部的 iterator_to_array($this) 与外部的 iterator_to_array($p) 不一样。但我很高兴它做到了!非常感谢。
  • 它的作用相同,但我将结果缓存到实例变量$dates,因此在随后调用toArray 时不再调用iterator_to_array。我只是返回了缓存的结果。
【解决方案2】:

我想知道迭代器是否没有被 iterator_to_array() 重新缠绕,所以第二个调用开始以光标结尾进行迭代。你可以试试这个:

$p->rewind()
$a=iterator_to_array($p); 

如果迭代器不可回退,您可以在遍历之前尝试克隆对象,例如

$p2 = clone $p;
echo count(iterator_to_array($p2));

$array = iterator_to_array($p);

【讨论】:

  • 看来 DatePeriod 没有倒带方法。 :( 文档说 DatePeriod 实现了 Traversable。但是 Traversable 是一个抽象接口,需要实现 Iterator 或 IteratorAggregate (在 DatePeriod 文档中都没有提到)。 IteratorAggregate 似乎没有公共倒带方法,所以也许 DatePeriod是它的孩子而不是迭代器?
  • 遗憾的是,克隆不是一个选项。它似乎会导致致命错误,但我不知道是什么类型的,因为它没有出现在网络日志中。
  • 就我而言,PHP 5.3 中的新日期和时间实现非常耗时。
【解决方案3】:

大概是第一次调用遍历迭代器中的所有元素(即调用 next() 直到 valid() 为 false)。明智的行为是 iterator_to_array 从迭代器中的当前位置开始转换 - 让它静默倒带是不灵活的,并且可能会导致错误。

在再次使用之前尝试倒回迭代器。

$p=new DatePeriod(date_create('2008-01-01'),
                  DateInterval::createFromDateString( "+2 days" ),
                  date_create('2008-12-31')); 

echo count(iterator_to_array($p)); //183 

$p->rewind(); // Newly added!

$a=iterator_to_array($p); 
echo count($a); //0

【讨论】:

    猜你喜欢
    • 2012-12-08
    • 1970-01-01
    • 1970-01-01
    • 2012-02-25
    • 2011-06-30
    • 2016-08-24
    相关资源
    最近更新 更多