Example usage of RecursiveArrayIterator
$array = array(
0 => 'a',
1 => array('subA','subB',array(0 => 'subsubA', 1 => 'subsubB', 2 => array(0 => 'deepA', 1 => 'deepB'))),
2 => 'b',
3 => array('subA','subB','subC'),
4 => 'c'
);
foreach (return new RecursiveIteratorIterator(new RecursiveArrayIterator($array))
as $key => $val) {
printf(
'%s: %s' . "
",
$key, $val
);
}
/* Output:
0: a
0: subA
1: subB
0: subsubA
1: subsubB
0: deepA
1: deepB
2: b
0: subA
1: subB
2: subC
4: c
*/
extending RecursiveIteratorIterator
to return the current key-stack
class MyRecursiveIteratorIterator extends RecursiveIteratorIterator
{
public function key() {
return json_encode($this->getKeyStack());
}
public function getKeyStack() {
$result = array();
for ($depth = 0, $lim = $this->getDepth(); $depth < $lim; $depth += 1) {
$result[] = $this->getSubIterator($depth)->key();
}
$result[] = parent::key();
return $result;
}
}
foreach ($it = new MyRecursiveIteratorIterator(new RecursiveArrayIterator($array))
as $key => $val) {
printf('%s (%s): %s' . "
", implode('.', $it->getKeyStack()), $key, $val);
}
/* Output:
0 ([0]): a
1.0 ([1,0]): subA
1.1 ([1,1]): subB
1.2.0 ([1,2,0]): subsubA
1.2.1 ([1,2,1]): subsubB
1.2.2.0 ([1,2,2,0]): deepA
1.2.2.1 ([1,2,2,1]): deepB
2 ([2]): b
3.0 ([3,0]): subA
3.1 ([3,1]): subB
3.2 ([3,2]): subC
4 ([4]): c
*/
Yet another version, using no RecursiveArrayIterator this time:
function flatten(array $array = array(), $keyStack = array(), $result = array()) {
foreach ($array as $key => $value) {
$keyStack[] = $key;
if (is_array($value)) {
$result = flatten($value, $keyStack, $result);
}
else {
$result[] = array(
'keys' => $keyStack,
'value' => $value
);
}
array_pop($keyStack);
}
return $result;
}
foreach (flatten($array) as $element) {
printf(
'%s: %s (depth: %s)' . "
",
implode('.', $element['keys']),
$element['value'],
sizeof($element['keys'])
);
}
/*
0: a (depth: 1)
1.0: subA (depth: 2)
1.1: subB (depth: 2)
1.2.0: subsubA (depth: 3)
1.2.1: subsubB (depth: 3)
1.2.2.0: deepA (depth: 4)
1.2.2.1: deepB (depth: 4)
2: b (depth: 1)
3.0: subA (depth: 2)
3.1: subB (depth: 2)
3.2: subC (depth: 2)
4: c (depth: 1)
*/