8

What's the best way to remove the parent of a matched key in an Multidimensional Array? For example, let's assume we have the following array and I want to find "[text] = a" and then delete its parent array [0]...

(array) Array
(

[0] => Array
    (
        [text] => a
        [height] => 30
    )

[1] => Array
    (
        [text] => k
        [height] => 30
    )
)
2
  • So, you wan't to delete rest of an parent array an have just first node from parent array? Commented Mar 7, 2010 at 10:08
  • Imagine the array went on like, [0],[1],[2],[3]... I would remove, or shift, [0] out. Commented Mar 9, 2010 at 21:44

5 Answers 5

7

Here’s the obvious:

foreach ($array as $key => $item) {
    if ($item['text'] === 'a') {
        unset($array[$key]);
    }
}
Sign up to request clarification or add additional context in comments.

5 Comments

this works in a 2 dimensional array, but not in general multidimensional arrays.
This was my first guess but, like you said, it's not recursive. Maybe, pushing it a bit more might help...
@Andres: Then how does such a multidimensional array look like where you would need recursion?
It worked!.. It's sometimes difficult to capture the representational meaning of arrays. I've always used $key => $val and didn't consider $key => $item... @Gumbo what if (in my example) [text] = array( [title] = "Hello", [body] = "this is a test" ) and I wanted to find and delete the parent of [title] = hello, which is [text]
@Andres: Try if ($item['text']['title'] === '…') unset($array[$key]['text']);.
4

using array_filter:

function filter_callback($v) {
  return !isset($v['text']) || $v['text'] !== 'a';
}
$array = array_filter($array, 'filter_callback');

this will only leave 'parent elements' in the array where text != a, therefore deleting those where text equals a

Comments

2

The inner arrays don't maintain any reference to their "parent" arrays, so you'd have to write a function to manually track this. Something like this might work:

function searchAndDestroy(&$arr, $needle) {
    foreach ($arr as &$item) {
        if (is_array($item)) {
            if (searchAndDestroy($item, $needle)) {
                return true;
            }
        } else if ($item === $needle) {
            $item = null;
            return true;
        }
    }
}

Note that this is designed to work at any level of nesting, not just two dimensions, so it might be a bit of overkill if you only need it for situations like in your example.

1 Comment

take note, the array key may not be numeric.
1

A simple and safe solution(I'd not remove/unset elements from an array I'm looping through) could be:

$new_array = array();
foreach($array as $item)
{
    if($item['text'] != "a")
    {
        $new_array[] = $item;
    }
}

Comments

0

My implementation:

function searchAndDestroy(&$a, $key, $val){
    foreach($a as $k => &$v){
        if(is_array($v)){
            $r = searchAndDestroy(&$v, $key, $val);
            if($r){
                unset($a[$k]);
            }
        }elseif($key == $k && $val == $v){
            return true;
        }
    }
    return false;
}

searchAndDestroy($arr, 'text', 'a');

To test it:

<pre><?php

function searchAndDestroy(&$a, $key, $val){
    foreach($a as $k => &$v){
        if(is_array($v)){
            $r = searchAndDestroy(&$v, $key, $val);
            if($r){
                unset($a[$k]);
            }
        }elseif($key == $k && $val == $v){
            return true;
        }
    }
    return false;
}

$arr = array(array('text'=>'a','height'=>'30'),array('text'=>'k','height'=>array('text'=>'a','height'=>'20')));

var_dump($arr);

searchAndDestroy($arr, 'text', 'a');

var_dump($arr);

?></pre>

This function does it recursively.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.