views:

53

answers:

1

I iterate through a multidimensional array with RecursiveIteratorIterator and would like to be able to know if the current element is the last child of it's depth. I thought about this:

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

But the RecursiveIteratorIterator says it's not cloneable.

+4  A: 

The phrase "last child of its depth" is not particularly clear. Could you elaborate on precisely what you mean; the intended use for this?

If you mean, quite simply, that the depth will change after the current element, then the (Recursive)CachingIterator has a handy hasNext method to determine whether the iterator has any further items. To give a watered-down example similar to that in the question:

$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";
    }
}

Outputs:

6 is the last child!
8 is the last child!
3 is the last child!
5 is the last child!
salathe
Oh darn... there already is an implementation for this, +1.
VolkerK
+1 nice use of SPL.
Russell Dias
I should really get around to documenting the caching iterators. (Any volunteers would be welcome.) I'm sure that the lack of docs is not making life easier for you guys! :)
salathe