PHP Recursively unset array keys if match

2019-01-09 10:52发布

问题:

I have the following array that I need to recursively loop through and remove any child arrays that have the key 'fields'. I have tried array filter but I am having trouble getting any of it to work.

$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')
                )
            )
        )
    )    
);

This is how I need it the result to look like:

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

回答1:

If you want to operate recursively, you need to pass the array as a reference, otherwise you do a lot of unnecessarily copying:

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


回答2:

you want array_walk

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


回答3:

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);
        }
    }
}


回答4:

My suggestion:

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');


回答5:

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);

Result:

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


回答6:

Give this function a shot. It will remove the keys with 'fields' and leave the rest of the array.

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


回答7:

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');


回答8:

Code:

$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);

Input:

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

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

)

Output:

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

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

)


回答9:

Recursively walk the array (by reference) and unset the relevant keys.

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:

I needed to have a little more granularity in unsetting arrays and I came up with this - with the evil eval and other dirty tricks.

$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']);