【问题标题】:Extending ArrayIterator and modifying array storage扩展 ArrayIterator 和修改数组存储
【发布时间】:2012-08-07 06:42:27
【问题描述】:

在扩展 ArrayIterator 时,如何访问当前数组来修改它?或者从中获取一些其他数据?

请考虑以下示例:

class Test extends ArrayIterator {
    public function in_array($key) {
        return in_array($key, ???);
    }
}

使用$this->getArrayCopy() 代替??? 好吗?有没有更好的解决方案来做到这一点?性能怎么样?

以及如何动态改变类的数组?例如使用 array_walk。

问候,

【问题讨论】:

    标签: php arrayiterator


    【解决方案1】:

    注意ArrayIterator 类实现了ArrayAccess。要修改数组,只需将 $this 视为数组即可:

    $this['k'] = 'v';
    

    不幸的是,in_array 等函数不适用于类似数组的对象;你需要一个实际的数组。 getArrayCopy() 可以,但我只会使用 (array) $this

    编辑:正如 salathe 评论中的注释,getArrayCopy() 更好,因为它总是获取内部数组,而如果您使用 STD_PROP_LIST 标志,(array) $this 的行为会有所不同。

    就性能而言,制作这样的数组副本确实会导致小幅减速。作为基准,我在 1000000 个项目的 ArrayIterator 上尝试了 getArrayCopy()(array),在我的机器上都花了大约 0.11 秒。另一方面,in_array 操作本身(在结果数组上)耗时 0.011 秒 - 大约只有十分之一。

    我也试过这个版本的in_array函数:

    class Test extends ArrayIterator {
        public function in_array($key) {
            foreach($this as $v)
                if($v == $key)
                    return true;
            return false;
        }
    }
    

    当搜索一个不存在的值时,该函数在我的机器上运行 0.07 秒,这是该算法的最坏情况。

    在大多数情况下,性能问题太小了。如果您的情况非常极端,以至于每个数组元素 100 纳秒左右实际上会产生影响,那么我建议您将要搜索的值放在数组键中并改用 offsetExists()

    【讨论】:

    • “使用(array) $this。他们做同样的事情。” — 不一定,该行为取决于所使用的标志。 ArrayIterator:: STD_PROP_LIST 将导致(array) $this 不是 是存储数组的表示;你可以猜到ArrayIterator::ARRAY_AS_PROPS 会做什么。 :)
    • 我已经为此添加了注释。 ARRAY_AS_PROPS 似乎并没有改变 (array) $this 的行为或性能,所以我把它省略了。
    猜你喜欢
    • 2013-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多