Question

I have this array

$array = Array
(
    Array
    (
        "id" => 1,
        "name" => "abc"
    ),
    Array
    (
        "id" => 2,
        "name" => 6
    ),
    Array
    (
        "id" => 3,
        "name" => "level 1",
        "sub_items" => Array
        (
            Array
            (
                "id" => 5,
                "name" => "level 2",
                "sub_items" => Array
                (
                    Array
                    (
                        "id" => 7,
                        "name" => "delete this!",
                        "sub_items" => Array
                        (
                            Array
                            (
                                "id" => 9,
                                "name" => "I will die too"
                            ),
                            Array
                            (
                                "id" => 10,
                                "name" => "I will die too"
                            )
                        )
                    )
                )
            ),
            Array
            (
                "id" => 6,
                "name" => "deleteeeeee me"
            ),
            Array
            (
                "id" => 8,
                "name" => "leave alone"
            )
        )
    ),
    Array
    (
        "id" => 4,
        "name" => "hello"
    )

);

What I want is to find a given node with certain key and value and delete it with all of it's sub nodes if they exists. So if want to delete ID = 6 then my array will be like this

Array
(
    [0] => Array
        (
            [id] => 1
            [name] => abc
        )

    [1] => Array
        (
            [id] => 2
            [name] => 6
        )

    [2] => Array
        (
            [id] => 3
            [name] => level 1
            [sub_items] => Array
                (
                    [0] => Array
                        (
                            [id] => 5
                            [name] => level 2
                            [sub_items] => Array
                                (
                                    [0] => Array
                                        (
                                            [id] => 7
                                            [name] => delete this!
                                            [sub_items] => Array
                                                (
                                                    [0] => Array
                                                        (
                                                            [id] => 9
                                                            [name] => I will die too
                                                        )

                                                    [1] => Array
                                                        (
                                                            [id] => 10
                                                            [name] => I will die too
                                                        )

                                                )

                                        )

                                )

                        )

                    [1] => Array
                        (
                            [id] => 8
                            [name] => leave alone
                        )

                )

        )

    [3] => Array
        (
            [id] => 4
            [name] => hello
        )

)

Or if I want to delete ID = 7 I will get:

Array
(
    [0] => Array
        (
            [id] => 1
            [name] => abc
        )

    [1] => Array
        (
            [id] => 2
            [name] => 6
        )

    [2] => Array
        (
            [id] => 3
            [name] => level 1
            [sub_items] => Array
                (
                    [0] => Array
                        (
                            [id] => 5
                            [name] => level 2
                            [sub_items] => Array
                                (

                                )

                        )

                    [1] => Array
                        (
                            [id] => 6
                            [name] => deleteeeeee me
                        )

                    [2] => Array
                        (
                            [id] => 8
                            [name] => leave alone
                        )

                )

        )

    [3] => Array
        (
            [id] => 4
            [name] => hello
        )

)

Some of the functions I've found just delete the key and not the entire structure. For example:

    Array
    (
        //here was "id" => 6
        "name" => "deleteeeeee me"
    ),

I should mention that the array can be N levels depth and can contain any kind of key-value pairs. So intead of ID = X / NAME = Y I could have VALUE = X / AMMOUNT = Y / LOCATION = Z

Here's a codepad with what I been working on so far.

Was it helpful?

Solution

The best way to do it is to use a recursive function (since your array is multidimensional). Since your keys are not defined upfront, a key name should be a param to this function. I assume sub_items is defined upfront as the key to the array holding sub-elements.

I would use something like this ($arr is an array on current level, notice the & in arguments forcing to pass arrays by reference):

//function definition for use later
function remove_element_by_key ($keyName, $keyValue, & $arr = array()) {

   //$arr is our current array, $ind is numerical index, $data is an array to compare keys
   foreach ($arr as $ind => & $data) {

      //check if current element is what we are looking for, ie. has 'id' => 6,
      //and remove it if it is
      if (array_key_exists($keyName, $data) && $data[$keyName] == $keyValue) {
         unset($arr[$ind]);
      }

      //if not - search it's subelements
      elseif (array_key_exists('sub_items', $data)) {
         remove_element_by_key($keyName, $keyValue, $data['sub_items']);
      }

   }
}

//and after definition just use this:
remove_element_by_key('id', 6, $yourWholeArray);

I haven't tested it, but this is surely the way to go.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top