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 PADS Logic 原理图
  • ¥15 PADS Logic 图标
  • ¥15 电脑和power bi环境都是英文如何将日期层次结构转换成英文
  • ¥20 气象站点数据求取中~
  • ¥15 如何获取APP内弹出的网址链接
  • ¥15 wifi 图标不见了 不知道怎么办 上不了网 变成小地球了
  • ¥50 STM32单片机传感器读取错误
  • ¥15 (关键词-阻抗匹配,HFSS,RFID标签天线)
  • ¥15 机器人轨迹规划相关问题
  • ¥15 word样式右侧翻页键消失