Skip to content
Advertisement

How do I get the value of the first occurrence of array_walk_recursive in php

I have a deep multidimensional array that I am needing to extract the value of a specific key. I have found that the array_walk_recursive function will be my best option. I only need the first occurrence.

My array looks like this – (except much more complicated)

Array (
    [vehicle info] => Array (
        [one] => Array (
            [submodel] => LX
            [engine] => 2.3
        )
        [two] => Array (
            [color] => blue
            [year] => 2007
            [wheels] => 4
        )
        [three] => Array (
            [submodel] => LX
            [make] => Ford
            [model] => F-150
            [offroad] => No
        )
    )
)

The issue here is, submodel is in both one and three. Additionally, the array is not consistent, so I must use array_walk_recursive to search through it for the matching key, then return the value for that key.

Here is my current code –

array_walk_recursive ($array, (function ($item, $key) {
    $wanted = "submodel";
    if ($key === $wanted) {
        echo ("$key is $item");
    }
}));

The above returns submodel is LXsubmodel is LX.

Bonus Question!! How can I search for multiple keys and return the first corresponding value for each of those? I was thinking putting all wanted keys in an array, then do a foreach loop, but don’t quite know how to structure this. I am new to php.

Advertisement

Answer

array_walk_recursive() is the appropriate native function to call for this task. Keep track of which keys have already been declared in the result array and ensure that they are never overwritten.

Code: (Demo)

$needles = ['submodel', 'offroad'];
$result = [];
array_walk_recursive(
    $array,
    function($value, $key) use ($needles, &$result) {
        if (
            in_array($key, $needles)
            && !isset($result[$key])
        ) {
            $result[$key] = "$key is $value";
        }
    }
);
var_export($result);

Output:

array (
  'submodel' => 'submodel is LX',
  'offroad' => 'offroad is No',
)

If your application has performance concerns, then the native function becomes less attractive because it will always iterate the entire input array’s structure — even after all sought keys are encountered. If you want to “break early” (short circuit), then you will need to design your own recursive function which will return when all sought keys are found.

Code: (Demo)

$soughtKeys = array_flip(['submodel', 'offroad']);

function earlyReturningRecursion(array $array, array $soughtKeys, array &$result = []): array
{
    foreach ($array as $key => $value) {
        if (!array_diff_key($soughtKeys, $result)) {  // check if result is complete
            return $result;
        } elseif (is_array($value)) {
            earlyReturningRecursion($value, $soughtKeys, $result);
        } elseif (isset($soughtKeys[$key]) && !isset($result[$key])) {
            $result[$key] = "$key is $value";
        }
    }
    return $result;
}
var_export(earlyReturningRecursion($array, $soughtKeys));
// same output as the first snippet
User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement