rsk82
rsk82

Reputation: 29387

how to get all keys that lead to given value when iterating multilevel array in php

Example:

$arr = array(array("name"=>"Bob","species"=>"human","children"=>array(array("name"=>"Alice","age"=>10),array("name"=>"Jane","age"=>13)),array("name"=>"Sparky","species"=>"dog")));
print_r($arr);

array_walk_recursive($arr, function($v,$k) {
    echo "key: $k\n";
});

The thing here is that I get only the last key, but I have no way to refer where I been, that is to store a particular key and change value after I left the function or change identical placed value in another identical array.

What I would have to get instead of string is an array that would have all keys leading to given value, for example [0,"children",1,"age"].

Edit: This array is only example. I've asked if there is universal way to iterate nested array in PHP and get full location path not only last key. And I know that there is a way of doing this by creating nested loops reflecting structure of the array. But I repeat: I don't know the array structure in advance.

Upvotes: 1

Views: 152

Answers (1)

Jan-Henk
Jan-Henk

Reputation: 4874

To solve your problem you will need recursion. The following code will do what you want, it will also find multiple paths if they exists:

$arr = array(
    array(
        "name"=>"Bob",
        "species"=>"human",
        "children"=>array(
            array(
                "name"=>"Alice",
                "age"=>10
            ),
            array(
                "name"=>"Jane",
                "age"=>13
            )
        ),
        array(
            "name"=>"Sparky",
            "species"=>"dog"
        )
    )
);

function getPaths($array, $search, &$paths, $currentPath = array()) {
    foreach ($array as $key => $value) {
        if (is_array($value)) {
            $currentPath[] = $key;
            if (true !== getPaths($value, $search, $paths, $currentPath)) {
                array_pop($currentPath);
            }
        } else {
            if ($search == $value) {
                $currentPath[] = $key;
                $paths[] = $currentPath;
                return true;
            }
        }
    }
}

$paths = array();
getPaths($arr, 13, $paths);
print_r($paths);

Upvotes: 2

Related Questions