Join the Stack Overflow Community
Stack Overflow is a community of 6.7 million programmers, just like you, helping each other.
Join them; it only takes a minute:
Sign up

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(
                )
            )
        )
    )    
);
share|improve this question
    
What value will "Part" have after the remove action? – powtac Nov 10 '09 at 15:41
    
I just need to unset 'fields' and leave part as 'array()' – SonnyBurnette Nov 10 '09 at 15:44

10 Answers 10

up vote 23 down vote accepted

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);
        }
    }
}
share|improve this answer
    
cool, I sure need to try this one! – Steward Godwin Jornsen Mar 3 '13 at 23:39
    
I'm not sure this is correct. From the php manual: If a variable that is PASSED BY REFERENCE is unset() inside of a function, only the local variable is destroyed. The variable in the calling environment will retain the same value as before unset() was called. php.net/manual/en/function.unset.php – Gerbus Aug 9 '13 at 3:35
    
@Gerbus: That statement only applies to the variable itself, not its values (or array-keys in this case). Altering the array itself does not invalidate the reference to the passed array. In other words: You would be correct if the code contained unset($array);, but this code unsets an array key. – soulmerge Aug 9 '13 at 8:40

you want array_walk

function remove_key(&$a) {
   if(is_array($a)) {
        unset($a['fields']);
        array_walk($a, __FUNCTION__);
   }
}
remove_key($myarray);
share|improve this answer
1  
Nice use of lambda + local constant, works in PHP 5.3+ – philwinkle Dec 27 '12 at 22:44
2  
Doesn't array_walk state that if you unset an element that the “behavior of this function is undefined, and unpredictable”? – greatwitenorth Aug 4 '13 at 4:14
    
@greatwitenorth, it does say that. This might work, but its probably best to avoid it sadly. – Aaron Aug 12 '13 at 21:11
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);
        }
    }
}
share|improve this answer
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 (
        ),
      ),
    ),
  ),
)
share|improve this answer

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;
}
share|improve this answer

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');
share|improve this answer
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');
share|improve this answer

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
        )

)
share|improve this answer

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);
    }
  }
}
share|improve this answer

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']);
share|improve this answer
    
Care to comment on the down vote? – Andy Gee Aug 28 '16 at 0:45

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.