teres
teres

Reputation: 415

Cannot remove specific item in array

I have an array that contains this items (content):

Array
(
    [0] => Array
        (
            [id] => 53
        )

    [1] => Array
        (
            [id] => 54
        )

    [2] => Array
        (
            [id] => 60
        )
)

I want to remove all the items that have a specific id available in another array, like: $to_remove = ["53", "54", "60"], what I did is:

foreach($to_remove as $id)
{
     $key = array_search($id, array_column($content, 'id'));
     unset($content[$key]);   
}

the problem is that in the final result I have:

Array
(
    [2] => Array
        (
            [answer] => >20%
            [points] => 3
            [id] => 60
        )

)

why?

Upvotes: 0

Views: 64

Answers (3)

The fourth bird
The fourth bird

Reputation: 163277

You use array_column($content, 'id') which will run 3 times due to the foreach giving you an array like this the first time.

Array
(
    [0] => 53
    [1] => 54
    [2] => 60
)

and the second time etc..

Array
(
    [0] => 54
    [1] => 60
)

.

Then array_search will return the first corresponding key for 53 the first time for which it find the key 0.

In the second loop, it searches for 54, and it finds key 0, and the third time it finds the key 1. So in your $content array, the unset will never be 2 and is not removed.

Another possibility to get your result is to use array_filter:

$content = array_filter($content, function($x) use($to_remove) {
    return !in_array($x["id"], $to_remove);
});

Php demo

Upvotes: 1

Barmar
Barmar

Reputation: 780889

The problem is that the array returned by array_column() doesn't use the same keys as the original array. The array it returns is indexed starting from 0, but unset doesn't reindex the array. So after you remove an element from the array, the indexes in the array are out of sync from the indexes of array_column($content, "id");

Instead of unset, use array_splice(). This adjusts all the indexes.

foreach($to_remove as $id)
{
     $key = array_search($id, array_column($content, 'id'));
     array_splice($content, $key, 1);   
}

Upvotes: 2

AbraCadaver
AbraCadaver

Reputation: 78994

Here's a fun way:

$content = array_intersect_key($content,
                               array_diff(array_column($content, 'id'), $to_remove));

Extract the id values from the original, compute the difference with $to_remove, then compute those key differences with the original.

Upvotes: 2

Related Questions