Take the tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

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!

share|improve this question
2  
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 '10 at 20:37
2  
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 '10 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 Kling Jan 5 '10 at 21:10
 
"Note: When foreach first starts executing, the internal array pointer is automatically reset to the first element of the array. This means that you do not need to call reset() before a foreach loop. As foreach relies on the internal array pointer changing it within the loop may lead to unexpected behavior." Taken from the php manual –  Vlad Balmos Dec 7 '11 at 15:05
add comment

7 Answers

foreach($images as $key => $image)
{
    if(in_array($image, array(
       'http://i27.tinypic.com/29ykt1f.gif',
       'http://img3.abload.de/img/10nxjl0fhco.gif',
       'http://i42.tinypic.com/9pp2tx.gif',
    ))
    {
        unset($images[$key]);
    }
}
share|improve this answer
 
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 '10 at 21:00
5  
Then try unset($images[1][$key]); –  hsz Jan 5 '10 at 21:11
add comment

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.

share|improve this answer
 
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 '10 at 21:03
 
This is the answer!!! –  ivantxo Jan 6 '12 at 23:14
1  
"The reference on &$image prevents the loop from creating a copy of the array which would waste memory." <- what I was looking for :) –  marcovtwout Jun 22 '12 at 13:11
add comment

$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]).

share|improve this answer
 
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. –  lnwdr Jan 5 '10 at 20:36
 
The second part is actually not so true. Sorry. Unsetting by reference does of course not work. –  lnwdr Jan 5 '10 at 20:42
 
@Techpriester: foreach does always work on an internal copy. –  Gumbo Jan 5 '10 at 20:43
add comment

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]);
    }
}
share|improve this answer
add comment

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.

share|improve this answer
2  
Format your code please :) –  Felix Kling Jan 5 '10 at 20:37
 
Fail. You should use code sample - not blockquote. ;) –  hsz Jan 5 '10 at 20:55
add comment

Sorry for the late response, I recently had the same problem with php and found out that when working with arrays that do not use $key => $value structure, when using the foreach loop you actual copy the value of the position on the loop variable, in this case $image. Try using this code and it will fix your problem.

for ($i=0; $i < count($images[1]); $i++) {

if($images[1][$i] == 'http://i27.tinypic.com/29yk345.gif' ||

    $images[1][$i] == 'http://img3.abload.de/img/10nx2340fhco.gif' ||

    $images[1][$i] == 'http://i42.tinypic.com/9pp2456x.gif')

{

    unset($images[1][$i]);

}

}

var_dump($images);die();

share|improve this answer
add comment

You would also need a

$i--;

after each unset to not skip an element/

Because when you unset $item[45], the next element in the for-loop should be $item[45] - which was [46] before unsetting. If you would not do this, you'd always skip an element after unsetting.

share|improve this answer
1  
But unset() will not change the array index so I don't think this $i-- is needed here. If the method array_splice() was used, then the elements would be shifted to cover the deleted hole and $i-- is necessary. –  zhujy_8833 Sep 18 '12 at 23:25
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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