I have a multidimensional array with an unknown number of levels. If a child array element contains a unique value, then how do I extract the parent array for use in PHP?
My array looks similar to this, except I don’t know how may grandparents the key/value has (or this would be a lot easier).
Array ( [0] => Array ( [blockName] => core/group, [attrs] => Array ( ), [innerBlocks] => Array ( // I want to extract this array if its [attrs] element contains [wrapper-id] => myUniqueID // The number of parents and grandparents is unknown. This is only an example. // Notice that other arrays contain attrs elements, but the value of this one is unique. [0] => Array ( [blockName] => lazyblock/zurb-tabs-wrapper, [attrs] => Array ( [wrapper-id] => myUniqueID, // This unique ID value is known. [blockId] => T, [blockUniqueClass] => lazyblock-zurb-tabs-wrapper-T ), [innerBlocks] => Array () ), // Later, I'll also want to extract this array based on its unique wrapper-id class. [1] => Array ( [blockName] => lazyblock/zurb-tabs-wrapper, [attrs] => Array ( [wrapper-id] => anotherUniqueID, // This unique ID value is known. [blockId] => T, [blockUniqueClass] => lazyblock-zurb-tabs-wrapper-T ), [innerBlocks] => Array () ) ) )
)
Finding the path to the parent might also work so I can walk to the values I need without extracting. That solution is similar to this getkeypath() function from Drummin , except the author is matching a key instead of a value. This is a problem for me because my key is is not unique, but my value is.
Advertisement
Answer
Recursive function is definitely the way to go with an unknown number of parents.
function getBlock(array $blocks, string $id): ?array { foreach ($blocks as $block) { // if the block has a wrapper-id attr and it matches the requested id, return it if (!empty($block['attrs']['wrapper-id']) && $block['attrs']['wrapper-id'] === $id) { return $block; } // check if we have inner blocks to iterate if (!empty($block['innerBlocks'])) { $innerBlock = getBlock($block['innerBlocks'], $id); if (!empty($innerBlock)) { return $innerBlock; } } } // fallback empty response return null; }
Then you’ll call the getBlock
method with your parent array.
$block = getBlock($blocks);