I am looking for a way to recursively delete parts of an array, and these part's children, by checking only keys.
In the example below $array is the input array, and $remove contains the keys that should be removed from $array:
$array = [
'key1' => [
'key11' => [],
'key12' => [
'key121' => [],
'key122' => [],
'key123' => [],
],
'key13' => [],
],
'key2' => [
'key21' => [],
'key22' => [],
'key23' => [],
'key24' => [],
'key25' => [
'key251' => [
'key2511' => [],
'key2512' => [],
'key2513' => [],
'key2514' => [],
'key2515' => [],
],
'key252' => [
'key2521' => [],
'key2522' => [],
'key2523' => [],
'key2524' => [],
'key2525' => [],
],
],
],
'key3' => [
'key31' => [],
'key32' => [],
'key33' => [],
'key34' => [],
'key35' => [
'key351' => [
'key3511' => [],
'key3512' => [],
'key3513' => [],
'key3514' => [],
'key3515' => [],
],
],
],
];
$remove = [
'key1' => [
'key12' => [
'key121' => [],
],
'key13' => [],
],
'key2' => [
'key25' => [
'key251' => [
'key2514' => [
],
],
'key252' => [],
],
],
'key3' => [],
];
I have written an ugly and non-recursive algorithm:
foreach ($array as $k1 => $v1) {
foreach ($v1 as $k2 => $v2) {
foreach ($v2 as $k3 => $v3) {
foreach ($v3 as $k4 => $v4) {
if (isset($array[$k1][$k2][$k3][$k4]) && isset($remove[$k1][$k2][$k3][$k4]) && 0 === count($remove[$k1][$k2][$k3][$k4])) {
unset($array[$k1][$k2][$k3][$k4]);
}
}
if (isset($array[$k1][$k2][$k3]) && isset($remove[$k1][$k2][$k3]) && 0 === count($remove[$k1][$k2][$k3])) {
unset($array[$k1][$k2][$k3]);
}
}
if (isset($array[$k1][$k2]) && isset($remove[$k1][$k2]) && 0 === count($remove[$k1][$k2])) {
unset($array[$k1][$k2]);
}
}
if (isset($array[$k1]) && isset($remove[$k1]) && 0 === count($remove[$k1])) {
unset($array[$k1]);
}
}
var_dump($array);
It returns the output that I am looking for:
array(2) {
["key1"]=>
array(2) {
["key11"]=>
array(0) {
}
["key12"]=>
array(2) {
["key122"]=>
array(0) {
}
["key123"]=>
array(0) {
}
}
}
["key2"]=>
array(5) {
["key21"]=>
array(0) {
}
["key22"]=>
array(0) {
}
["key23"]=>
array(0) {
}
["key24"]=>
array(0) {
}
["key25"]=>
array(1) {
["key251"]=>
array(4) {
["key2511"]=>
array(0) {
}
["key2512"]=>
array(0) {
}
["key2513"]=>
array(0) {
}
["key2515"]=>
array(0) {
}
}
}
}
}
My question is, how can I make this functionality recursive, as in theory, $array could be nested indefinitely?
Any help would be gratefully accepted. Thank you!
In the meantime, I came up with an alternative solution:
function array_remove_key_recursive($input, $remove)
{
$ret = [];
foreach ($input as $key => $value) {
if (array_key_exists($key, $remove)) {
if (is_array($value)) {
if (count($remove[$key]) > 0) {
$diff_recursive = array_remove_key_recursive($value, $remove[$key]);
if (count($diff_recursive) > 0) {
$ret[$key] = $diff_recursive;
}
}
} else {
if ($value != $remove[$key]) {
$ret[$key] = $value;
}
}
} else {
$ret[$key] = $value;
}
}
return $ret;
}
Here is how I would do it
function test (&$arr, $remove) {
$keys =array_keys ($remove, [], true) ;
$arr =array_filter ($arr, function ($v, $k) use ($remove, $keys) {
return !in_array ($k, $keys, true) ;
},
ARRAY_FILTER_USE_BOTH
) ;
$keys =array_diff (array_keys ($remove), $keys) ;
foreach ( $keys as $key )
test ($arr [$key], $remove [$key]) ;
}
test ($array, $remove) ;
print_r ($array) ;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With