【问题标题】:Remove subtree in multi-dimensional array by dot-separated key通过点分隔键删除多维数组中的子树
【发布时间】:2018-03-01 06:56:11
【问题描述】:

我想通过点分隔键删除特定的子数组。这里有一些工作(是的,它工作但甚至不是一个好的解决方案)代码:

$Data = [
                'one',
                'two',
                'three' => [
                    'four' => [
                        'five' => 'six', // <- I want to remove this one
                        'seven' => [
                            'eight' => 'nine'
                        ]
                    ]
                ]
            ];

            # My key
            $key = 'three.four.five';
            $keys = explode('.', $key);
            $str = "";
            foreach ($keys as $k) {
                $sq = "'";
                if (is_numeric($k)) {
                    $sq = "";
                }
                $str .= "[" . $sq . $k . $sq . "]";
            }
            $cmd = "unset(\$Data{$str});";
            eval($cmd); // <- i'd like to get rid of this evil shit

对此有更好的解决方案的任何想法?

【问题讨论】:

    标签: php arrays


    【解决方案1】:

    您可以使用references 来执行此操作。需要注意的重要一点是你不能取消设置变量,但你可以unset a array key

    解决办法如下代码

    # My key
    $key = 'three.four.five';
    $keys = explode('.', $key);
    // No change above here
    
    
    // create a reference to the $Data variable
    $currentLevel =& $Data;
    $i = 1;
    foreach ($keys as $k) {
        if (isset($currentLevel[$k])) {
            // Stop at the parent of the specified key, otherwise unset by reference does not work
            if ($i >= count($keys)) {
                unset($currentLevel[$k]);
            }
            else {
                // As long as the parent of the specified key was not reached, change the level of the array
                $currentLevel =& $currentLevel[$k];
            }
        }
        $i++;
    }
    

    【讨论】:

      【解决方案2】:

      您可以使用对数组内元素的引用,然后删除 $keys 数组的最后一个键。

      您应该添加一些错误处理/检查键是否确实存在,但这是基础:

      $Data = [ 
                  'one',
                  'two',
                  'three' => [
                      'four' => [
                          'five' => 'six', // <- I want to remove this one
                          'seven' => [
                              'eight' => 'nine'
                          ]
                      ]
                  ]
      ];
      
      # My key
      $key = 'three.four.five';
      $keys = explode('.', $key);
      
      $arr = &$Data;
      while (count($keys)) {
          # Get a reference to the inner element
          $arr = &$arr[array_shift($keys)];
      
          # Remove the most inner key
          if (count($keys) === 1) {
              unset($arr[$keys[0]]);
              break;
          }
      }
      
      var_dump($Data);
      

      A working example.

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-09-20
        • 2013-11-05
        • 2014-05-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-08-17
        相关资源
        最近更新 更多