9

How can I delete an element from a multi-dimensional array given a key?

I am hoping for this to be greedy so that it deletes all elements in an array that match the keys I pass in. I have this so far where I can traverse a multi-dimensional array but I can't unset the key I need to because I don't have a reference to it!

function traverseArray($array, $keys)
{ 
    foreach($array as $key=>$value)
    { 
        if(is_array($value))
        { 
            traverseArray($value); 

        } else {

            if(in_array($key, $keys))
           {                    
                //unset(what goes here?) 

            }

        } 
    }

}
1
  • I think Call-time pass-by-reference has been deprecated. Especially since I am using this in a class in Code-igniter. Commented Aug 20, 2011 at 21:45

4 Answers 4

8

The following code works (and doesn't use deprecated stuff), just tested it:

function traverseArray(&$array, $keys) { 
  foreach ($array as $key => &$value) { 
    if (is_array($value)) { 
      traverseArray($value, $keys); 
    } else {
      if (in_array($key, $keys)){
        unset($array[$key]);
      }
    } 
  }
}
Sign up to request clarification or add additional context in comments.

1 Comment

This was very useful, thanks @Marian. If anyone uses this and wants to perform a check on the VALUE of the element you're removing, you can check $value just before performing unset();
1

You could use pass by reference, declare your function like this:

function traverseArray(&$array, $keys)
{ 
    foreach($array as $key=>$value)
    { 
        if(is_array($value))
        { 
            traverseArray($value, $keys); 
        }else{
            if(in_array($key, $keys)){
                unset($array[$key]);
            }
        } 
    }
}

then you can unset the key and it will vanish from the original passed value too since the $array in the function is merely a pointer to the array you passed so it updates that array.

unset($array[$key]);

For more information check the php documentation on passing by reference

4 Comments

I get this message Call-time pass-by-reference has been deprecated. I am using this in a class in Codeigniter.
I edited my answer to include your whole function. Additionally you need to make sure that when you call it you use traverseArray($array, $keys) and not traverseArray(&$array, $keys)
Right, I don't get that error anymore. However, the array is the same as before. I am wondering can this really work in a class? I am calling the above function from another function in a class and this function isn't returning anything. The way I call it is like so: $this->traverseArray($errors, array('e1', 'e2'));
@Abs Marian Galik beat me to finding the bug and his code works, Andrej L had already figured out that little part of it.
0

You can do this

unset($array[$key]);

because $array will not be a copy of the original array, just a reference to it, so any modifications will hold.

Also, you have a small bug in your snippet: when you make the recursive call, you forget the pass the $keys parameter.

2 Comments

@sg3s in new versions (php5.x, don't know for sure) it's the default + the pass-by-reference &$var is deprecated. See this answer (stackoverflow.com/questions/6138454/…) for clarification.
I'm quite sure @sg3's right. The & in a function call, like foo(&$a); is deprecated according to the manual, but otherwise it says function foo(&$var) {.
0

and don't forget to modify foreach:

foreach($array as $key=>&$value)

3 Comments

You don't need to do this once a variable is referenced it will carry it through to all the uses of that variable afaik (someone feel to test this? :p)
You can't change array values in foreach.
What is reason for downvoting?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.