Php 仅通过检查键递归删除数组元素及其子元素
我正在寻找一种方法,通过只检查键,递归地删除数组的部分以及这些部分的子元素 在下面的示例中,$array是输入数组,$remove包含应从$array中删除的键:Php 仅通过检查键递归删除数组元素及其子元素,php,arrays,recursion,diff,Php,Arrays,Recursion,Diff,我正在寻找一种方法,通过只检查键,递归地删除数组的部分以及这些部分的子元素 在下面的示例中,$array是输入数组,$remove包含应从$array中删除的键: $array = [ 'key1' => [ 'key11' => [], 'key12' => [ 'key121' => [], 'key122' => [], 'key123' =>
$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' => [],
];
我写了一个丑陋的非递归算法:
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);
它返回我要查找的输出:
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) {
}
}
}
}
}
我的问题是,如何使这个函数递归,就像理论上,$array可以无限嵌套一样
任何帮助都将被感激地接受。谢谢大家!
与此同时,我提出了另一种解决方案:
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;
}
我会这样做的
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) ;
这是一个递归执行所需操作的函数
function remove_by_keys(array $array, array $remove)
{
// Copy the input array into the result; will remove parts of it
// according to the information stored in $remove
$result = $array;
// Check the keys to remove
foreach ($remove as $key => $value) {
if ($value === []) {
// Remove the key and the entire value associated with the key
unset($result[$key]);
} else {
// Keep the key, recursively remove parts of the value (next level)
$result[$key] = remove_by_keys($array[$key], $remove[$key]);
}
}
return $result;
}
工作原理:
该函数接收两个参数:$array
是输入数组,$remove
是要从$array
中删除的键(和子键)列表
它复制输入数组,然后分析键(
$key
)和$remove
的值。如果值为[]
(空数组),则将从结果中完全删除$array
的相应键和值。如果$remove[$key]
不是[]
,则递归调用$array[$key]
和$remove[$key]
(下一级)函数,它返回的值(过滤后的$array[$key]
)存储在结果数组中的$key
添加所有代码,这解释了您的问题,您的问题代码已按要求添加到问题中。谢谢您的回答。我对它进行了测试,结果与预期相符。谢谢你的解决方案。它非常简单。我最喜欢的解决方案!