recursive function : filtering large multidimensional array by key element to HTML list I have a multidimensional array as a result from a webservice called from PHP. I cannot edit the webservice, but the result is as

array (size=5)
  'id' =&gt; int 0
  'name' =&gt; 
    array (size=7)
      'it' =&gt; string 'Tutti' (length=5)
      'ca' =&gt; string 'Tots' (length=4)
      'es' =&gt; string 'Todos' (length=5)
      'de' =&gt; string 'Alle' (length=4)
      'fr' =&gt; string 'Tous' (length=4)
      'nl' =&gt; string 'Alle' (length=4)
      'en' =&gt; string 'All' (length=3)
  'tree' =&gt; 
    array (size=0)
      empty
  'languages' =&gt; 
    array (size=7)
  'subTypes' =&gt; 
    array (size=4)
      0 =&gt; 
        array (size=5)
          'id' =&gt; int 1
          'name' =&gt; 
            array (size=29)
              ...
          'tree' =&gt; 
            array (size=1)
              ...
          'languages' =&gt; 
            array (size=29)
              ...
          'subTypes' =&gt; 
            array (size=3)
              ...
      1 =&gt; 
        array (size=5)
          'id' =&gt; int 2
          'name' =&gt; 
            array (size=29)
              ...
          'tree' =&gt; 
            array (size=1)
              ...
          'languages' =&gt; 
            array (size=29)
             ...
          'subTypes' =&gt; 
            array (size=6)
              ...


As you can see, you can interpret it as a multidimensional array of objects. Each objects can have child objects of same type.

My goal is to get only the elements on a specific language, fe en (and thus rest is not taken). I thought to use a recursive function.

// filter array
function getByKey($array, $search, $level, $valuesUsed) {
    echo '&lt;ul&gt;';
    foreach($array as $key =&gt; $value) {
        if(is_array($array[$key])) {
            $valuesUsed = getByKey($array[$key], $search, $level + 1, $valuesUsed);
        } else if ($key === $search) {
            if(!in_array($value, $valuesUsed)) {
                echo "&lt;li&gt; $key = $value &lt;/li&gt;";
                $valuesUsed[] = $value;
            }
        }
    }
    echo '&lt;/ul&gt;';
    return $valuesUsed;
}


Then I call the above function from my HTML template by

&lt;div id="foo"&gt;
    &lt;?php
        getByKey($routeTypes, 'en', 0, array());
    ?&gt;
&lt;/div&gt;


$routeTypes is the array, obtained from the webservice. 
It works as expected, it results as the list here below, which I can wrap with a js library.

&lt;ul&gt;
   &lt;li&gt;this is level1&lt;/li&gt;
   &lt;li&gt;this is level1&lt;/li&gt;
   &lt;li&gt;
       &lt;ul&gt;
           &lt;li&gt;this is level 2&lt;/li&gt;
           &lt;li&gt;this is level 2&lt;/li&gt;
           &lt;li&gt;
               ... level++
           &lt;/li&gt;
       &lt;/ul&gt;
   &lt;/li&gt;
&lt;/ul&gt;


Now, I'm questioning myself if this can be improved ? It doesn't take long to have a list from a large multidimensional array. (a simple print_r command resulted in 45000+ characters). 

Especially checking the $valuesUsed array, to prevent duplicates (yes the webservice has objects which contains child keys which is similar to level - 2 parent (or on other level ...... ))

Each time I am running through the lower levels, I am looping through the $valuesUsed array. Is there not a better way to loop through the sublevels ? Maybe an array_walk() or array_walk_recursive() with a callback function ?
You can choose a (key => value) pair recursively with this function:

function array_value_recursive($key, array $arr){
    $val = array();
    array_walk_recursive($arr, function($v, $k) use($key, &amp;$val){
        if($k == $key) array_push($val, $v);
    });
    return count($val) &gt; 1 ? $val : array_pop($val);
}


This function makes use of array_walk_recursive() to push into a placeholder array whatever value is pointed to by whichever key matches our needle key. 

Proof code:

$array = array(
    'id' =&gt; 0,
    'name' =&gt; array(
        'it' =&gt; 'Tutti',
        'ca' =&gt; 'Tots',
        'es' =&gt; 'Todos', 
        'de' =&gt; 'Alle' ,
        'fr' =&gt; 'Tous',
        'nl' =&gt; 'Alle',
        'en' =&gt; 'All'
    ),
    'languages' =&gt; array(
        "d" =&gt; 33
    ),
    'subTypes' =&gt; array(
        0 =&gt; array(
            'id' =&gt; 1,
            'name' =&gt; array(
                'it' =&gt; 'Tutti',
                'ca' =&gt; 'Tots',
                'es' =&gt; 'Todos', 
                'de' =&gt; 'Alle' ,
                'fr' =&gt; 'Tous',
                'nl' =&gt; 'Alle',
                'en' =&gt; 'All'
            )
        ),
        1 =&gt; array(
            'id' =&gt; 1,
            'name' =&gt; array(
                'it' =&gt; 'Tutti',
                'ca' =&gt; 'Tots',
                'es' =&gt; 'Todos', 
                'de' =&gt; 'Alle' ,
                'fr' =&gt; 'Tous',
                'nl' =&gt; 'Alle',
                'en' =&gt; 'All'
            )
        ),
        2 =&gt; array(
            'id' =&gt; 1,
            'name' =&gt; array(
                'it' =&gt; 'Tutti',
                'ca' =&gt; 'Tots',
                'es' =&gt; 'Todos', 
                'de' =&gt; 'Alle' ,
                'fr' =&gt; 'Tous',
                'nl' =&gt; 'Alle',
                'en' =&gt; 'All'
            )
        )
    )
);

print_r(array_value_recursive("de", $array));


The above test code, which seeks all "de" keys, will output: 

Array ( 
    [0] =&gt; Alle 
    [1] =&gt; Alle 
    [2] =&gt; Alle 
    [3] =&gt; Alle
)