Php, Spl, ArrayIterator

Я пытаюсь понять кусок кода:

$array = array('koala', 'kangaroo', 'wombat', 'wallaby', 'emu', 'kiwi', 'kookaburra', 'platypus');
$object = new ArrayIterator($array);
foreach($object as $key=>$value)
{
if($object->offSetGet($key) === 'kiwi')
{
$object->offSetUnset($key);
}
echo $key.' - '.$value."<br />";
}

Я пытался понять, почему offSetUnset берет указатель на второй элемент массива, а не на первый. Моя теория представляет собой следующую последовательность событий:

Когда вызывается offSetUnset, указатель переходит к элементу 0, offSetUnset ждет, пока foreach запрашивает элемент, тогда offSetUnset знает, что может действовать, поэтому, когда это происходит, он удаляет элемент, указанный ранее, когда он заканчивает итерацию, он переходит к элементу. следующий элемент, и поэтому я думаю, что мы теряем элемент 0 после того, как offSetUnset сбросил цикл foreach.

Но, как я уже сказал, это всего лишь теория, которую я придумал, прежде чем спросить здесь, поэтому, если кто-нибудь может провести меня через последовательность событий, из-за которой мы потеряли 0-й элемент, всем спасибо и хорошего дня.


person Aviel Fedida    schedule 13.09.2012    source источник


Ответы (2)


Существует задокументированная ошибка, которая звучит очень "близко" к ошибке, которую вы обнаружили найдено!
Чтобы обойти это, вы можете сделать следующее:

$array = array('koala', 'kangaroo', 'wombat', 'wallaby', 'emu', 'kiwi', 'kookaburra', 'platypus');
$object = new ArrayIterator($array);
for ( $object->rewind(); $object->valid(); $object->next() )
{
    if($object->current() === 'kiwi')
    {
        $object->offsetUnset( $object->key() );
    }
    echo $object->key().' - '.$object->offsetGet($object->key())."\n";
}

Вывод:

0 - koala
1 - kangaroo
2 - wombat
3 - wallaby
4 - emu
0 - koala  (this time it starts over from the first element!)
1 - kangaroo
2 - wombat
3 - wallaby
4 - emu
6 - kookaburra
7 - platypus

Если вы хотите, вы можете отправить сообщение об ошибке, но согласно другим темам, которые я видел ошибки в ArrayIterator - мне трудно поверить, что это будет исправлено в ближайшее время...

person Nir Alfasi    schedule 13.09.2012
comment
Спасибо, Альфасин, хорошего дня. - person Aviel Fedida; 13.09.2012

Вот использование offsetUnset, когда элементы сбрасываются по их индексу и дают ожидаемый результат:

$array = array('koala', 'kangaroo', 'wombat', 'wallaby', 'emu', 'kiwi', 'kookaburra', 'platypus');

$object = new \ArrayIterator($array);

foreach ($object->getArrayCopy() as $i => $item) {
    if($item === 'kiwi') {
        $object->offsetUnset( $i );
    }
}

print_r($object->getArrayCopy());

Вывод:

Array ( [0] => koala [1] => kangaroo [2] => wombat [3] => wallaby [4] => emu [6] => kookaburra [7] => platypus )
person Tsounabe    schedule 02.03.2017
comment
спасибо чувак -. ваше решение также ответило на мою проблему, за исключением того факта, что я использовал ArrayObject;) way/" title="arrayobjectoffsetunset неожиданно перемещает внутренний указатель"> stackoverflow.com/questions/50000613/ - person sintakonte; 24.04.2018