RecursiveIteratorIterator последний дочерний элемент

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

$iterator = new RecursiveIteratorIterator($array,
  RecursiveIteratorIterator::SELF_FIRST);    
foreach ($iterator as $val) {
  $next = clone $iterator;
  $next->next();
  $lastChild = ($next->getDepth() < $iterator->getDepth());
}

Но RecursiveIteratorIterator говорит, что его нельзя клонировать.


person sod    schedule 28.09.2010    source источник
comment
@Bobby: Почему тег spl бессмыслен? Это определенно вопрос SPL.   -  person Dennis Haarbrink    schedule 28.09.2010
comment
@Dennis Haarbrink: На SO есть только 42 вопроса, помеченных [SPL], поэтому я не уверен, добавляет ли это что-то ценное к вопросу. Я также не уверен, что это не будет синонимом самого [php], поскольку я также не помечаю вопросы C# тегами [mscoree] или [System-Data]. Но это, возможно, стоит обсудить на Meta.   -  person Bobby    schedule 28.09.2010
comment
Я пометил итератор php loops последним ребенком, не понимаю ваших комментариев.   -  person sod    schedule 28.09.2010
comment
@Bobby: я полагаю, что если тег существует и он активен (и, конечно, описывает проблему), вы должны его использовать. Является ли это ценным тегом, конечно, спорно.   -  person Dennis Haarbrink    schedule 28.09.2010
comment
@sod: проверьте историю изменений вопроса. Я добавил тег spl, но Бобби удалил его.   -  person Dennis Haarbrink    schedule 28.09.2010
comment
@sod: И я удалил тег [last-child]. @Dennis Haarbrink: я снова добавлю это (потому что я сомневаюсь) и спрошу на Meta. Спасибо за терпение.   -  person Bobby    schedule 28.09.2010
comment
Как бы вы обработали элемент на глубине = 2, следующий элемент на глубине = 3, следующий элемент на глубине = 1? Все еще действует как «потеря своей глубины», но следующая глубина скорее выше, чем ниже...   -  person Wrikken    schedule 28.09.2010


Ответы (1)


Фраза «последний ребенок его глубины» не особенно ясна. Не могли бы вы уточнить, что именно вы имеете в виду; предполагаемое использование для этого?

Если вы просто имеете в виду, что глубина изменится после текущего элемента, то у (Recursive)CachingIterator есть удобный метод hasNext, чтобы определить, есть ли у итератора какие-либо дополнительные элементы. Чтобы привести разбавленный пример, аналогичный тому, что в вопросе:

$array  = array(
    range(1,6),
    range(7,8),
    'foo' => range(1,3),
    'bar' => range(4,5),
);

$rit = new RecursiveArrayIterator($array);
$iterator = new RecursiveIteratorIterator(
    new RecursiveCachingIterator($rit),
    RecursiveIteratorIterator::LEAVES_ONLY
);
foreach ($iterator as $val) {
    $lastChild = !$iterator->hasNext();
    if ($lastChild) {
        echo "$val is the last child!\n";
    }
}

Выходы:

6 is the last child!
8 is the last child!
3 is the last child!
5 is the last child!
person salathe    schedule 28.09.2010
comment
Мне действительно нужно заняться документированием итераторов кэширования. (Любые добровольцы приветствуются.) Я уверен, что отсутствие документов не облегчает вам жизнь, ребята! :) - person salathe; 28.09.2010
comment
прошло почти ровно шесть лет, а легче не стало... - person James Alday; 16.09.2016
comment
В PHP 7.2 этот код дает сбой при преобразовании массива в строку. Что изменилось в RecursiveCachingIterator? - person temuri; 26.07.2019
comment
@temuri не сбой (по умолчанию), но выдаст E_NOTICE начиная с PHP 5.4, потому что итератор кэширования пытается преобразовать массивы в строки во время итерации. Это связано с тем, что значение по умолчанию для параметра $flags конструктора RecursiveCachingIterator равно RecursiveCachingIterator::CALL_TOSTRING. Чтобы этого не произошло, вы можете передать 0 или RecursiveCachingIterator:: TOSTRING_USE_KEY или RecursiveCachingIterator:: TOSTRING_USE_CURRENT для параметра $flags. - person salathe; 27.07.2019