dongruo0909 2019-05-10 11:59
浏览 220
已采纳

按键递归删除嵌套数组中的元素(array_filter_recursive)

I want to be able to remove elements from the multidimentianal array by key

Example of such an array can be:

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] => private@tulik.io
                        )
                )

        )
)

I have two methods, recursiveArrayDelete removes any elements where the callback returns 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;
}

Second, removes properties all included in restrictedProperties from the 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 alwalys false
                 return $bool; 
             });
    }

    return $array;
}

Example of usage:

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

Should remove these elements from array. But as I mentioned in commenrt sanitizedArray where return $bool; always result in false

  • 写回答

2条回答 默认 最新

  • doujiang3997 2019-05-10 14:11
    关注

    @dWinder's answer is almost perfect. But when I played around with it a bit more I noticed that it would not delete an array under a given "restricted property".

    Let us assume that all "D"-elements were to be removed:

    dWinder's solution would result in:

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

    The array under "D" is still there. But when you switch the if condition and action with that of the else if you get the (assumed!) desired result:

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

    So, the improved function code should look something like this (I am quoting parts of @dWinder's solution here):

    $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);
    

    See here for a demo: https://3v4l.org/05tc7

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 网络设备配置与管理这个该怎么弄
  • ¥20 机器学习能否像多层线性模型一样处理嵌套数据
  • ¥20 西门子S7-Graph,S7-300,梯形图
  • ¥50 用易语言http 访问不了网页
  • ¥50 safari浏览器fetch提交数据后数据丢失问题
  • ¥15 matlab不知道怎么改,求解答!!
  • ¥15 永磁直线电机的电流环pi调不出来
  • ¥15 用stata实现聚类的代码
  • ¥15 请问paddlehub能支持移动端开发吗?在Android studio上该如何部署?
  • ¥20 docker里部署springboot项目,访问不到扬声器