如果黑名单数组中存在键,则递归地从嵌套数组中删除元素

问题描述 投票:0回答:2

我希望能够通过

key

从多维数组中删除元素

此类数组的示例可以是:

Array
(
    [data] => Array
        (
            [todo] => code review
            [schedule] => Array
                (
                    [endDate] => 2019-05-10T00:00:00+01:00
                    [startDate] => 2019-05-09T00:00:00+01:00
                )

            [codeDetails] => Array
                (
                    [language] => PHP
                    [type] => class
                    [abstract] => true
                    [methodCount] => Array
                        (
                            [public] => 3
                            [protected] =>
                            [private] => 1
                        )

                    [LOC] => 123
                    [cyclomaticComplexity] => 4
                    [author] => Array (
                            [name] => Lukasz
                            [email] => [email protected]
                        )
                )

        )
)

我有两种方法,

recursiveArrayDelete
删除回调返回的所有元素
true

private function recursiveArrayDelete(array &$array, callable $callback): array
{
    foreach ($array as $key => &$value) {
        if (is_array($value)) {
            $value = $this->recursiveArrayDelete($value, $callback);
        }
        if ($callback($value, $key)) {
            unset($array[$key]);
        }
    }

    return $array;
}

其次,从

restrictedProperties
中删除
array
中包含的所有属性:

private function sanitizedArray(array &$array, array &$restrictedProperties): array
{
    foreach ($restrictedProperties as $restrictedProperty) {
        $this->recursiveArrayDelete(
            $array,
             static function () use ($array, $restrictedProperty): bool {
                array_walk_recursive(
                    $array,
                    static function ($value, $key) use (&$bool, $restrictedProperty) {
                         // here $bool is as expected from condition
                         $bool = $key === $restrictedProperty;
                     });
                  // here is always false
                 return $bool; 
             });
    }

    return $array;
}

使用示例:

$this->sanitizedResponse($data, ['methodCount', `endDate`]);

应该从数组中删除这些元素。但正如我在评论

sanitizedArray
中提到的,其中
return $bool;
总是导致
false

php arrays recursion multidimensional-array filtering
2个回答
2
投票

@dWinder 的答案几乎是完美的。但是当我更多地使用它时,我注意到它不会删除给定“受限属性”下的数组。 让我们假设所有

"D"

元素都将被删除:


dWinder 的解决方案将导致:

Array ( [A] => aa [B] => Array ( [A] => aaa [B] => bb ) [C] => cc [D] => Array ( [E] => ee ) )

"D"

下的数组仍然存在。但是,当您将

if
的条件和操作与
else if
的条件和操作切换时,您会得到(假设!)所需的结果:

Array ( [A] => aa [B] => Array ( [A] => aaa [B] => bb ) [C] => cc )

所以,改进后的函数代码应该是这样的(我在这里引用了@dWinder解决方案的部分内容):

$arr = array("A" => "aa", "B" => ["A" => "aaa", "B" => "bb"], "C" => "cc", "D" => ["E" =>"ee"]); function array_filter_recursive(array &$array, callable $callback) { foreach ($array as $key => &$value) { if ($callback($key, $value)) unset($array[$key]); else if (is_array($value)) array_filter_recursive($value, $callback); } } function sanitizedArray(&$arr, $restrictedProperties) { foreach($restrictedProperties as $prop) { array_filter_recursive($arr, function($k, $v) use ($prop) {return $prop == $k;}); } } sanitizedArray($arr, ["D"]); print_r($arr);

请参阅此处的演示:
https://3v4l.org/05tc7


2
投票
$bool

- 所以只有最后一个比较才算数(这就是为什么您总是得到 false 的原因)。


我会让你的代码更简单这样:

function array_filter_recursive(array &$array, callable $callback) { foreach ($array as $key => &$value) { if ($callback($key, $value)) unset($array[$key]); else if (is_array($value)) array_filter_recursive($value, $callback); } } function sanitizedArray(&$arr, $restricted, $keys = false) { foreach($restricted as $val) { array_filter_recursive($arr, function($k, $v) use ($val, $keys) {return $keys ? ($val === $k) : ($val === $v);}); } }

现在您可以简单地使用它作为示例:
$this->sanitizedResponse($data, ['methodCount', 'endDate'], true);


这是带有虚假数据的实时示例:

3v4l

© www.soinside.com 2019 - 2024. All rights reserved.