PHP如果匹配则递归取消设置数组键

时间:2009-11-10 15:37:44

标签: php arrays recursion

我有以下数组,我需要递归循环并删除任何具有键'字段'的子数组。我已经尝试了数组过滤器,但我无法使其中任何一个工作。

$myarray = array(
    'Item' => array(
        'fields' => array('id', 'name'),
        'Part' => array(
            'fields' => array('part_number', 'part_name')
        )
    ),
    'Owner' => array(
        'fields' => array('id', 'name', 'active'),
        'Company' => array(
            'fields' => array('id', 'name',),
            'Locations' => array(
                'fields' => array('id', 'name', 'address', 'zip'),
                'State' => array(
                    'fields' => array('id', 'name')
                )
            )
        )
    )    
);

这就是我需要它的结果:

$myarray = array(
    'Item' => array(
        'Part' => array(
        )
    ),
    'Owner' => array(
        'Company' => array(
            'Locations' => array(
                'State' => array(
                )
            )
        )
    )    
);

11 个答案:

答案 0 :(得分:31)

如果要以递归方式操作,则需要将数组作为reference传递,否则会进行大量不必要的复制:

function recursive_unset(&$array, $unwanted_key) {
    unset($array[$unwanted_key]);
    foreach ($array as &$value) {
        if (is_array($value)) {
            recursive_unset($value, $unwanted_key);
        }
    }
}

答案 1 :(得分:5)

你想要array_walk

function remove_key(&$a) {
   if(is_array($a)) {
        unset($a['fields']);
        array_walk($a, __FUNCTION__);
   }
}
remove_key($myarray);

答案 2 :(得分:2)

function recursive_unset(&$array, $unwanted_key) {

    if (!is_array($array) || empty($unwanted_key)) 
         return false;

    unset($array[$unwanted_key]);

    foreach ($array as &$value) {
        if (is_array($value)) {
            recursive_unset($value, $unwanted_key);
        }
    }
}

答案 3 :(得分:1)

我的建议:

function removeKey(&$array, $key)
{
    if (is_array($array))
    {
        if (isset($array[$key]))
        {
            unset($array[$key]);
        }
        if (count($array) > 0)
        {
            foreach ($array as $k => $arr)
            {
                removeKey($array[$k], $key);
            }
        }
    }
}

removeKey($myarray, 'Part');

答案 4 :(得分:1)

function sanitize($arr) {
    if (is_array($arr)) {
        $out = array();
        foreach ($arr as $key => $val) {
            if ($key != 'fields') {
                $out[$key] = sanitize($val);
            }
        }
    } else {
        return $arr;
    }
    return $out;
}

$myarray = sanitize($myarray);

结果:

array (
  'Item' => 
  array (
    'Part' => 
    array (
    ),
  ),
  'Owner' => 
  array (
    'Company' => 
    array (
      'Locations' => 
      array (
        'State' => 
        array (
        ),
      ),
    ),
  ),
)

答案 5 :(得分:1)

function removeRecursive($haystack,$needle){
    if(is_array($haystack)) {
        unset($haystack[$needle]);
        foreach ($haystack as $k=>$value) {
            $haystack[$k] = removeRecursive($value,$needle);
        }
    }
    return $haystack;
}

$new = removeRecursive($old,'key');

答案 6 :(得分:0)

给这个功能一个机会。它将删除带有“字段”的键,并保留数组的其余部分。

function unsetFields($myarray) {
    if (isset($myarray['fields']))
        unset($myarray['fields']);
    foreach ($myarray as $key => $value)
        $myarray[$key] = unsetFields($value);
    return $myarray;
}

答案 7 :(得分:0)

代码:

$('.slideToCart').css({
  '-webkit-transform' : 'translate(left, top)',
  '-moz-transform'    : 'translate(left, top)',
  '-ms-transform'     : 'translate(left, top)',
  '-o-transform'      : 'translate(left, top)',
  'transform'         : 'translate(left, top)'
});

$('.slideToCart').css('transform', 'translate(50px, 50px)');
$('.slideToCart').css('-webkit-transform', 'translate(50px, 50px)');

输入:

$sweet = array('a' => 'apple', 'b' => 'banana');
$fruits = array('sweet' => $sweet, 'sour' => $sweet);

function recursive_array_except(&$array, $except)
{
  foreach($array as $key => $value){
    if(in_array($key, $except, true)){
      unset($array[$key]);
    }else{
      if(is_array($value)){
        recursive_array_except($array[$key], $except);
      }
    }
  }
  return;
}

recursive_array_except($fruits, array('a'));
print_r($fruits);

输出:

Array
(
    [sweet] => Array
        (
            [a] => apple
            [b] => banana
        )

    [sour] => Array
        (
            [a] => apple
            [b] => banana
        )

)

答案 8 :(得分:0)

我想出了一个简单的函数,可用于基于多个键删除多个数组元素。

Detail example here

只需更改一下代码即可。

function removeRecursive($inputArray,$delKey){
    if(is_array($inputArray)){
        $moreKey    =   explode(",",$delKey);
        foreach($moreKey as $nKey){
            unset($inputArray[$nKey]);
            foreach($inputArray as $k=>$value) {
                $inputArray[$k] = removeRecursive($value,$nKey);
            }
        }
    }
    return $inputArray;
}

$inputNew   =   removeRecursive($input,'keyOne,keyTwo');

print"<pre>";
print_r($inputNew);
print"</pre>";

答案 9 :(得分:-1)

递归遍历数组(通过引用)并取消设置相关的键。

clear_fields($myarray);
print_r($myarray);

function clear_fields(&$parent) {
  unset($parent['fields']);
  foreach ($parent as $k => &$v) {
    if (is_array($v)) {
      clear_fields($v);
    }
  }
}

答案 10 :(得分:-1)

我需要在未设置的数组中有更多的粒度,我想出了这个 - 用邪恶的评估和其他肮脏的技巧。

$post = array(); //some huge array

function array_unset(&$arr,$path){
    $str = 'unset($arr[\''.implode('\'][\'',explode('/', $path)).'\']);';
    eval($str);
}

$junk = array();
$junk[] = 'property_meta/_edit_lock';
$junk[] = 'property_terms/post_tag';
$junk[] = 'property_terms/property-type/0/term_id';
foreach($junk as $path){
    array_unset($post,$path);
}

// unset($arr['property_meta']['_edit_lock']);
// unset($arr['property_terms']['post_tag']);
// unset($arr['property_terms']['property-type']['0']['term_id']);