0

I'm working on documenting an API, so I am parsing example XML/JSOn output and need to find all the named keys to add definitions. So, I have an array like this:

$array = [
  "user" => [
    "name" => "John",
    "email" => "[email protected]",
    "products" => [
      0 => "product A",
      1 => "product B"
    ],
    "files" => [
      "logo" => "/path/logo.jpg",
      "profile" => "/path/profile.jpg"
    ]
  ],
  "offer" => [
    0 => "My offer"
  ]
];

And I want to extract all the keys from the array, no matter its depth, and get an output akin to:

$keys = [
  0 => ["user"],
  1 => ["user", "name"],
  2 => ["user", "email"],
  3 => ["user", "products"],
  4 => ["user", "files"],
  5 => ["user", "files", "logo"],
  6 => ["user", "files", "profile"],
  7 => ["offer"]
];

Note that keys that are numeric are ignored, only named keys are included in the hierarchy. I have googled and tried to find something that does this, but I've come up blank. I have tried some function chaining but I just can't wrap my head around the loops and returns correctly. Any help is appreciated!

3
  • 2
    " I have tried some function chaining", please show us your attempt! Commented May 26, 2021 at 10:31
  • 2
    Does this answer your question? PHP function to get recursive path keys with path Commented May 26, 2021 at 10:36
  • @0stone0 Not really, it ignores the first level "user" and "product" and includes numerical keys, I'll see if I canm tweak it. It's very similar to my own efforts though Commented May 26, 2021 at 10:45

1 Answer 1

0

Ok, with help of @0stone0 I was directed to a Stackoverflow answer that led me right, this is the end function:

function definitionTree(array $array): array{
    $tree = function($siblings, $path) use (&$tree) {
        $result = [];
        foreach ($siblings as $key => $val) {
            $currentPath = is_numeric($key) ? $path : array_merge($path, [$key]);
            if (is_array($val)) {
                if (!is_numeric($key)) $result[] = join(' / ', $currentPath);
                $result = array_merge($result, $tree($val, $currentPath));
            } else {
                $result[] = join(' / ', $currentPath);
            }
        }
        return $result;
    };
    $paths = $tree($array, []);
    return array_unique($paths);
}

Which returns the following:

Array
(
    [0] => user
    [1] => user / name
    [2] => user / email
    [3] => user / products
    [6] => user / files
    [7] => user / files / logo
    [8] => user / files / profile
    [9] => offer
)
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.