vote up 1 vote down star
3

I need to have access to a array which looks like this.

Array
(
    [0] => Array
        (

            [54] => Array
            (
                [test] => 54
                [tester] => result
            )
         )
)

foreach($array as $key=>$value)
{
  echo $key;// prints 0
  echo $value;// prints Array
  /*
   now i can iterate through $value but i dont want it solve that way example:
  foreach($value as $k=>$v)
  {
    echo $k;//prints test
    echo $v; //prints 54
  }
  */

}

How can iterate just once ? to get the values of test and tester? I hope i could explain my problem clear

flag

Does the array have only one array (which contains more arrays) or does it have many arrays which contain many arrays? You need to give a slightly better example for your test array. – zaf Apr 13 at 13:13
And do you allow other functions like array_map etc...? – zaf Apr 13 at 13:15
@zaf its a array which contains many arrays – streetparade Apr 13 at 13:17

3 Answers

vote up 4 vote down check

Use SPL's RecursiveDirectoryIterator

$iterator = new RecursiveIteratorIterator(
                new RecursiveArrayIterator($array), 
                RecursiveIteratorIterator::SELF_FIRST);

foreach($iterator as $key => $val) {
    if($key === 'test' || $key === 'tester') {
        echo "$key = $val \n";
    }
}

This will find all array elements with a value of either test or tester, regardless of where it appears in the multidimensional array. If you have to narrow it to a specific depth in the array, you can match against $iterator->getDepth().


You can also put the if condition into the method body of a FilterIterator's accept() method, e.g.

class TestFilter extends FilterIterator
{
    public function accept()
    {
        return ($this->key() === 'test' || $this->key() === 'tester');
    }
}

and then wrap the iterator in it before foreaching it, e.g.

$iterator = new TestFilter($iterator); // wrap iterator from first example
foreach($iterator as $key => $val) {
    echo "$key = $val \n";    
}

Further reading:

link|flag
Thanks i will give it a try – streetparade Apr 13 at 13:20
For what it's worth, if my interpretation of the question is correct in that you just want to get the deepest (i.e. non-array) items from the array then life could be made somewhat simpler by using new RecursiveIteratorIterator(new RecursiveArrayIterator($array)) and not having any condition within the foreach loop. – salathe yesterday
@salathe granted, if you take the OP's example literally, then the default LEAVES_ONLY would be sufficient. – Gordon yesterday
vote up 1 vote down

You could use an anonymous function to list the items. This will use recursion every time an array is encountered as an element:

array_walk_recursive($array, create_function('$item, $key', 
    'echo "$key => $item<br />";'
));

Or when using PHP 5.3:

array_walk_recursive($array, function($item, $key) { 
    echo "$key => $item<br />";
});

This will be faster (and more readable) than create_function(). However this construct is only available in PHP 5.3 and up.

Both will output:

test => 54
tester => result

Which is exactly what you want, I believe.

link|flag
vote up 0 vote down

This would only work for this specific array:

foreach($array[0][54] as $key=>$value)
{
    echo $key;// prints test and tester
    echo $value;// prints 54 and result
}
link|flag
Noop thats not what i need it should also woth for [120][2] and soon – streetparade Apr 13 at 13:17
This answer shouldn't have been voted down, fair enough it's way too specific, but the question didn't really provide much in the way of a proper array structure, just a very basic example. – ILMV Apr 13 at 13:34

Your Answer

Get an OpenID
or
never shown

Not the answer you're looking for? Browse other questions tagged or ask your own question.