由于 ArrayIterator 不是真正的列表,因此“append”的实现有点让我困惑。使用“append”时,我期望新值位于“最后一个元素索引 + 1”的位置。当您在之前取消设置元素时,这不会发生。
似乎一旦使用了索引,就会被列入黑名单并且永远不会再次使用,即使它们被取消设置。
如 https://php.net/manual/de/arrayiterator.offsetset.php#106775 中所建议的,ArrayIterator::append 使用带有空索引参数的 ArrayIterator::offsetSet。因此,我有以下两种解决方法来使“append”按我想要的方式工作
<?php
类 myArrayIterator 扩展 ArrayIterator {
公共函数 offsetSet($offset, $value) {
如果 (is_null($offset)) { // offset == null 当它被 ArrayIterator::append 调用时
$offset = $this->generateOffset(); // 在单独的方法中执行
}
parent::offsetSet($offset, $value); // 使用索引调用本机实现
$this->ksort(); // 对其进行排序以避免在转储或迭代时出现混淆
}
受保护的函数 generateOffset() {
$offset = count($this); // 以计数作为偏移量,因为它应该是 lastKey+1
当 ($this->offsetExists($offset)) { // 它是否真的为空?
$offset++; // 尝试下一个直到有一个空的吗
}
返回 $offset;
}
}
类 mySaveArrayIterator 扩展 myArrayIterator {
受保护的函数 generateOffset() {
$offset = 0; // 预期 0 是第一个可能的键
当 ($this->offsetExists($offset)) { // 尝试每个键直到有一个空的吗
$offset++;
}
返回 $offset;
}
}
$data = 数组('foo', 'bar', 'baz');
$array = 新 ArrayIterator($data);
$myArray = 新 myArrayIterator($data);
$mySaveArray = 新 mySaveArrayIterator($data);
// 删除最后一个元素
$array ->offsetUnset(2);
$myArray ->offsetUnset(2);
$mySaveArray->offsetUnset(2);
// 追加一个元素
$array ->append('foobar');
$myArray ->append('foobar');
$mySaveArray->append('foobar');
// 检查新元素的位置
print_r($array);
print_r($myArray);
print_r($mySaveArray);
// 删除一些元素
$array ->offsetUnset(1);
$myArray ->offsetUnset(1);
$mySaveArray->offsetUnset(1);
// 再次追加一个元素
$array ->append('foobarbaz');
$myArray ->append('foobarbaz');
$mySaveArray->append('foobarbaz');
// 检查新元素的位置
print_r($array);
print_r($myArray);
print_r($mySaveArray);
?>
输出
ArrayIterator 对象
(
[storage:ArrayIterator:private] => 数组
(
[0] => foo
[1] => bar
[3] => foobar
)
)
myArrayIterator 对象
(
[storage:ArrayIterator:private] => 数组
(
[0] => foo
[1] => bar
[2] => foobar
)
)
mySaveArrayIterator 对象
(
[storage:ArrayIterator:private] => 数组
(
[0] => foo
[1] => bar
[2] => foobar
)
)
ArrayIterator 对象
(
[storage:ArrayIterator:private] => 数组
(
[0] => foo
[3] => foobar
[4] => foobarbaz
)
)
myArrayIterator 对象
(
[storage:ArrayIterator:private] => 数组
(
[0] => foo
[2] => foobar
[3] => foobarbaz
)
)
mySaveArrayIterator 对象
(
[storage:ArrayIterator:private] => 数组
(
[0] => foo
[1] => foobarbaz
[2] => foobar
)
)
这帮助我将 ArrayIterator 视为一个具有有效索引的按顺序排列的列表。