I have a multidimensional array with an indeterminant depth. I want to keep only some keys depending a collection of paths, but I need a generic, recursive function and not a hardcoded filter.
Example:
$originalArray = array(
'key1' => array(
'key1' => 'value1',
'key2' => 'value2',
),
'key2' => array(
'key1' => 'value3',
'key2' => 'value4',
'key3' => array(
'key1' => 'value5',
'key2' => array(
'key1' => 'value6',
'key2' => 'value',
),
),
),
'key3' => array(
"key1" => "value1",
"key2" => array(
array(
'key1' => 'value1',
'key2' => 'value2',
'key3' => 'value2',
),
array(
'key1' => 'value1',
'key2' => 'value2',
'key3' => 'value3',
),
)
),
);
$pathsToRetain = array(
array('key1', 'key1'),
array('key2', 'key1'),
array('key2', 'key3', 'key1'),
array('key2', 'key3', 'key2', 'key1'),
array("key3", "key2", "*", 'key1'),
array("key3", "key2", "*", 'key3')
);
$this->filterArrayByPath($originalArray, pathsToRetain);
Result shoud be :
$result = array(
'key1' => array(
'key1' => 'value1',
),
'key2' => array(
'key1' => 'value3',
'key3' => array(
'key1' => 'value5',
'key2' => array(
'key1' => 'value6',
),
),
),
'key3' => array(
"key2" => array(
array(
'key1' => 'value1',
'key3' => 'value2',
),
array(
'key1' => 'value1',
'key3' => 'value3',
),
)
),
);
One of the difficulties is on wildcard for arrays without key (key3->key2 contains arrays without keys and I want to apply the filter to both of them, or use 0, 1, 3 as key if not wildcard)
2
Answers
This can be done using a recursive function.
Give this ago:
I’ve fashioned a recursive script to remove disqualified elements while modifying the input array by reference. If you refer for the function to "return" the modified payload, you can
return $array
at the end; but just keep in mind that your original input array WILL be mutated by this function.The demo link has some additional commented checkpoints if you’d like to see the progress internally.
The script will iterate the current level of the input array and check the first values of each row in the path array. If a qualifying key is found, then a flag is set to not unset the element. If the element qualifies and there are more paths to traverse, then the function is called again with reduced parameters.
Code: (Demo)