Php 仅通过检查键递归删除数组元素及其子元素

Php 仅通过检查键递归删除数组元素及其子元素,php,arrays,recursion,diff,Php,Arrays,Recursion,Diff,我正在寻找一种方法,通过只检查键,递归地删除数组的部分以及这些部分的子元素 在下面的示例中,$array是输入数组,$remove包含应从$array中删除的键: $array = [ 'key1' => [ 'key11' => [], 'key12' => [ 'key121' => [], 'key122' => [], 'key123' =>

我正在寻找一种方法,通过只检查键,递归地删除数组的部分以及这些部分的子元素

在下面的示例中,$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;
}

我会这样做的

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

添加所有代码,这解释了您的问题,您的问题代码已按要求添加到问题中。谢谢您的回答。我对它进行了测试,结果与预期相符。谢谢你的解决方案。它非常简单。我最喜欢的解决方案!