以递归方式从多维数组中删除特定键

时间:2014-10-30 19:36:24

标签: php arrays multidimensional-array

我正在尝试创建一个从动态多维数组中删除键的函数,我需要给出:

removeByIndex(['hello', 'my', 'world']);

然后该功能需要这样做:

unset($array['hello']['my']['world']);

索引的数量是动态的,例如:

removeByIndex(['hello', 'my']); // Do: unset($array['hello']['my']);
removeByIndex(['hello']); // Do: unset($array['hello']);

我尝试使用一些foreach循环,但我还没有找到解决方案。

欢迎任何帮助。

3 个答案:

答案 0 :(得分:2)

不需要eval()进行一些引用。     

/**
 * Remove index from multi-dimensional array.
 *
 * @param array $array
 *   The array to remove the index from.
 * @param array $indices
 *   Indexed array containing the indices chain up to the index that should be
 *   removed.
 * @return
 *   The array with the index removed.
 * @throws \InvalidArgumentException
 *   If the index does not exist within the array.
 */
function removeByIndex(array $array, array $indices) {
  // Create a reference to the original array.
  $a =& $array;

  // Count all passed indices, remove one because arrays are zero based.
  $c = count($indices) - 1;

  // Iterate over all passed indices.
  for ($i = 0; $i <= $c; ++$i) {
    // Make sure the index to go down for deletion actually exists.
    if (array_key_exists($indices[$i], $a)) {
      // This is the target if we reached the last index that was passed.
      if ($i === $c) {
        unset($a[$indices[$i]]);
      }
      // Make sure we have an array to go further down.
      elseif (is_array($a[$indices[$i]])) {
        $a =& $a[$indices[$i]];
      }
      // Index does not exist since there is no array to go down any further.
      else {
        throw new \InvalidArgumentException("{$indices[$i]} does not exist.");
      }
    }
    // Index does not exist, error.
    else {
      throw new \InvalidArgumentException("{$indices[$i]} does not exist.");
    }
  }

  return $array;
}

print_r(removeByIndex(
  [ "test1" => [ "test2" => [ "test3" => "test" ] ], "test4" => "test" ],
  [ "test1", "test2", "test3" ]
));

由于我在评论中提到它,可以(微)优化函数,但我反对它,因为它不太可读,可能会让一些程序员感到困惑。

<?php

function removeByIndex(array $array, array $indices) {
  $a =& $array;
  $c = count($indices) - 1;
  $i = 0;
  do {
    if (array_key_exists($indices[$i], $a)) {
      if ($i === $c) {
        unset($a[$indices[$i]]);
        return $array;
      }
      elseif (is_array($a[$indices[$i]])) {
        $a =& $a[$indices[$i]];
      }
      else break;
    }
    else break;
  }
  while (++$i);
  throw new \InvalidArgumentException("{$indices[$i]} does not exist.");
}

答案 1 :(得分:1)

基于辉煌的@Fleshgrinder答案,我正在使用这个最终版本:

function removeByIndex($vars, $indexes) {
    if ( ! is_array($indexes)) {
        throw new \Exception('Array expected');
    }

    $array = & $vars;

    $qtd_indexes = count($indexes);

    for ($i = 0; $i < $qtd_indexes; $i++) {
        if ( ! array_key_exists($indexes[$i], $array)) {
          throw new \Exception($indexes[$i] . " doesn't exist");
        }

        // Check if it is the target entry
        if ($i === $qtd_indexes - 1) {
            unset($array[$indexes[$i]]);
        } elseif (is_array($array[$indexes[$i]])) { // Check if exists one more level
            $array = & $array[$indexes[$i]];
        } else {
            // If it isn't the target and it isn't an array, throw exception
            throw new \Exception("Content of '" . $indexes[$i] . "' isn't an array");
        }
    }

    return $vars;
}

答案 2 :(得分:1)

我为此解决方案研究了几个小时,没有找到最佳解决方案。所以,我自己写了

function allow_keys($arr, $keys)
    {
        $saved = [];

        foreach ($keys as $key => $value) {
            if (is_int($key) || is_int($value)) {
                $keysKey = $value;
            } else {
                $keysKey = $key;
            }
            if (isset($arr[$keysKey])) {

                $saved[$keysKey] = $arr[$keysKey];
                if (is_array($value)) {

                    $saved[$keysKey] = allow_keys($saved[$keysKey], $keys[$keysKey]);
                }
            }
        }
        return $saved;
    }

使用:示例

$array = [
        'key1' => 'kw',
        'loaa'=> ['looo'],
        'k'    => [
            'prope' => [
                'prop'  => ['proo', 'prot', 'loolooo', 'de'],
                'prop2' => ['hun' => 'lu'],
            ],
            'prop1' => [

            ],
        ],
    ];

致电:示例

allow_keys($array, ['key1', 'k' => ['prope' => ['prop' => [0, 1], 'prop2']]])

输出:

Array ( [key1] => kw [k] => Array ( [prope] => Array ( [prop] => Array ( [0] => proo [1] => prot ) [prop2] => Array ( [hun] => lu ) ) ) ) 

因此您只需从多维数组中获取所需的键。它不仅限于“多维”,你可以通过传递像

这样的数组来使用它
['key1', 'loaa']

输出你得到:

Array ( [key1] => kw [loaa] => Array ( [0] => looo ) )

我在这里写这篇文章是因为这个主题是你在google上输入的第一个

  

递归删除键多维php

希望有人帮助这个,因为我经常搜索,没有找到任何东西。 干杯!