我正在寻找一种通过仅检查键来递归删除数组的部分以及这些部分的子项的方法。
在下面的示例中,$ array是输入数组,$ remove包含应从$ 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' => [],
];
我写了一个丑陋且非递归的算法:
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;
}
答案 0 :(得分:2)
我将如何做到这一点
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) ;
答案 1 :(得分:1)
这是一个递归地执行您需要的功能。
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
的结果数组中。