vote up 1 vote down star

I have a foreach loop set up to go through my array, check for a certain link, and if it finds it removes that link from the array.

My code:

foreach($images as $image)
{
    if($image == 'http://i27.tinypic.com/29yk345.gif' ||
    $image == 'http://img3.abload.de/img/10nx2340fhco.gif' ||
    $image == 'http://i42.tinypic.com/9pp2456x.gif')
    {
        unset($images[$image]);
    }
}

But it doesn't remove the array entires. It's probably something to do with $images[$image], as that's not the key of the array entry, only the content? Is there a way to do this without incorporating a counter?

Thanks.

EDIT: Thanks guys, but now I have another problem where the array entries don't actually get deleted.

My new code:

foreach($images[1] as $key => $image)
{
    if($image == 'http://i27.tinypic.com/29yk345.gif')
    $image == 'http://img3.abload.de/img/10nx2340fhco.gif' ||
    $image == 'http://i42.tinypic.com/9pp2456x.gif')
    {
        unset($images[$key]);
    }
}

$images is actuallty a two-dimensional array now hence why I need $images[1]. I have checked and it successfully goes around the array elements, and some elements do actually have some of those URLs in that I wish to delete, but they're not getting deleted. This is my $images array:

Array
(
    [0] => Array
        (
            [0] => useless
            [1] => useless
            [2] => useless
            [3] => useless
            [4] => useless
        )

    [1] => Array
        (
            [0] => http://i27.tinypic.com/29yk345.gif
            [1] => http://img3.abload.de/img/10nx2340fhco.gif
            [2] => http://img3.abload.de/img/10nx2340fhco.gif
            [3] => http://i42.tinypic.com/9pp2456x.gif
        )

)

Thanks!

flag

38% accept rate
1  
I would also suggest if(in_array($image, array('i27.tinypic.com/29yk345.gif', 'img3.abload.de/img/10nx2340fhco.gif', 'i42.tinypic.com/9pp2456x.gif')). Makes it more readable ;) – Olivier Lalonde Jan 5 at 20:37
1  
Since you changed the array you're iterating, that needs to be reflected in your call to unset - unset($images[1][$key]); – bish Jan 5 at 21:03
And the parenthesis in the if statement are wrong but I guess this just typo (otherwise you would get an error message) – Felix Jan 5 at 21:10

5 Answers

vote up 8 vote down
foreach($images as $key => $image)
{
    if($image == 'http://i27.tinypic.com/29ykt1f.gif' ||
    $image == 'http://img3.abload.de/img/10nxjl0fhco.gif' ||
    $image == 'http://i42.tinypic.com/9pp2tx.gif')
    {
        unset($images[$key]);
    }
}
link|flag
Thanks for the help, but I'm having trouble actually deleting some of the array elements. See the edit in the first post :) – Matt Jan 5 at 21:00
2  
Then try unset($images[1][$key]); – hsz Jan 5 at 21:11
vote up 3 vote down

$image is in your case the value of the item and not the key. Use the following syntax to get the key too:

foreach ($images as $key => $value) {
    /* … */
}

Now you can delete the item with unset($images[$key]).

link|flag
This might work, but it will still copy the whole array to execute the foreach loop. So it's a waste of memory. If I'm not mistaken, the approach with references (see my answer) is also faster than resolving the key/value pair each time the unset happens. – Techpriester Jan 5 at 20:36
The second part is actually not so true. Sorry. Unsetting by reference does of course not work. – Techpriester Jan 5 at 20:42
@Techpriester: foreach does always work on an internal copy. – Gumbo Jan 5 at 20:43
vote up 1 vote down

One solution would be to use the key of your items to remove them -- you can both the keys and the values, when looping using foreach.

For instance :

$arr = array(
    'a' => 123,
    'b' => 456,
    'c' => 789, 
);

foreach ($arr as $key => $item) {
    if ($item == 456) {
        unset($arr[$key]);
    }
}

var_dump($arr);

Will give you this array, in the end :

array
  'a' => int 123
  'c' => int 789


Which means that, in your case, something like this should do the trick :

foreach($images as $key => $image)
{
    if($image == 'http://i27.tinypic.com/29yk345.gif' ||
    $image == 'http://img3.abload.de/img/10nx2340fhco.gif' ||
    $image == 'http://i42.tinypic.com/9pp2456x.gif')
    {
        unset($images[$key]);
    }
}
link|flag
vote up 1 vote down

Try that:

foreach ($images as $key => &$image) {
    if (yourConditionGoesHere) {
        unset($images[$key])
    }
}

Normally, foreach operates on a copy of your array so any changes you make, are made to that copy and don't affect the actual array.

So you need to unset the values via $images[$key];

The reference on &$image prevents the loop from creating a copy of the array which would waste memory.

link|flag
Thanks. I think what you're saying is related to my problem (see edit). Even if I add a & though it still doesn't work. – Matt Jan 5 at 21:03
vote up 0 vote down

foreach($images as $key=>$image)                                
{               
   if($image == 'http://i27.tinypic.com/29ykt1f.gif' ||    
   $image == 'http://img3.abload.de/img/10nxjl0fhco.gif' ||    
   $image == 'http://i42.tinypic.com/9pp2tx.gif')     
   { unset($images[$key]); }                               
}

!!foreach($images as $key=>$image

cause $image is the value, so $images[$image] make no sense.

link|flag
2  
Format your code please :) – Felix Jan 5 at 20:37
just for you ;) – pinusnegra Jan 5 at 20:50
Fail. You should use code sample - not blockquote. ;) – hsz Jan 5 at 20:55
:D oh sh*t,ok now okay – pinusnegra Jan 5 at 21:00

Your Answer

Get an OpenID
or
never shown

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