PHP - 通过给定的键路径从数组中删除项目(在另一个数组中)

时间:2014-09-17 08:58:01

标签: php arrays

我有一个问题需要解决。 将有两个数组:

<?php
$main_array = array(
  'item-1' => array(
    'item-1-1' => array(
      'item-1-1-1' => 'value',
      'item-1-1-2' => 'value',
    ),
    'item-1-2' => 'value'
  ),
  'item-2' => 'value',
  'item-3' => array(
    'item-3-1' => array(
      'item-3-1-1' => 'value',
      'item-3-1-2' => 'value',
    ),
    'item-3-2' => 'value',
  ),
);

$key_paths_to_deleted = array(
  array('item-1', 'item-1-1', 'item-1-1-1'),
  array('item-2'),
  array('item-3', 'item-3-1'),
);

我需要从$main_array中给出的基于$key_paths_to_deleted的索引路径中删除项目。因此产生的$main_array应如下所示。

$main_array = array(
  'item-1' => array(
    'item-1-1' => array(
      'item-1-1-2' => 'value',
    ),
    'item-1-2' => 'value'
  ),
  'item-3' => array(
    'item-3-2' => 'value',
  ),
);

这意味着我将要删除主阵列中的项目。

主数组中的键和值可以是PHP中的任何可能值,没有键的结构化命名,值可能是重复的。

提前致谢。

2 个答案:

答案 0 :(得分:1)

只需遍历路径并按照该路径行进,直至找到目的地unset()

示例:

foreach ($key_paths_to_deleted as $parts) {
  $target = &$main_array;
  $last = count($parts) - 1;
  for ($i = 0; $i <= $last; $i++) {
    if ($i == $last) {
      unset($target[$parts[$i]]);
    } else {
      $target = &$target[$parts[$i]];
    }
  }
}
unset($target); // Don't leave references hanging around.

var_export($main_array);

输出:

array (
  'item-1' => 
  array (
    'item-1-1' => 
    array (
      'item-1-1-2' => 'value',
    ),
    'item-1-2' => 'value',
  ),
  'item-3' => 
  array (
    'item-3-2' => 'value',
  ),
)

答案 1 :(得分:0)

函数remove()是递归的,将检查参数中的键。如果找到密钥,它将删除它。

参数$last表示它是否是最后一个键。 在您的示例中,它会删除item-3-1的所有内容,但不会删除item-3

function remove(&$array, $remove, $last = false)
{
  foreach($array as $key => &$value) {
    if(is_array($value)) remove($value, $remove, $last);

    if(is_array($value) && $key == $remove && $last == true) unset($array[$key]);
    if( !is_array($value) && $key == $remove) unset($array[$key]);
  }
}

for ( $i = 0 ; $i < count($key_paths_to_deleted) ; $i++ )
{
  $last = count($key_paths_to_deleted[$i]) - 1;

  for ( $j = $last; $j >= 0 ; $j-- )
    remove($main_array, $key_paths_to_deleted[$i][$j], ( $j == $last ) ? true : false);
}

结果:

Array
(
    [item-1] => Array
        (
            [item-1-1] => Array
                (
                    [item-1-1-2] => value
                )

            [item-1-2] => value
        )
    [item-3] => Array
        (
            [item-3-2] => value
        )
)