AgA
AgA

Reputation: 2126

Using nested foreach loop on same array

Is it ok to loop array again in nested loop and also change the array?

I've an URL's array with entries(as array key) of either an URL or domain:example.com

In case of this entry : domain:example.com I want to remove all URLS containing example.com as domain:

foreach (array_keys($urls1) as $line) {
        if (preg_match('/domain:(.*)/i', $line, $matches)) {
            $domain = $matches[1];
            foreach (array_keys($urls1) as $line2) {
                if ($url_domains[$line2] == $domain) {
                    unset($urls1[$line2]);
                }
            }
        }
    }

Upvotes: 5

Views: 4982

Answers (2)

Growling Flea
Growling Flea

Reputation: 119

I ran into a similar problem and making a copy of the array was the answer. This was my problem:

If a particular text string existed towards the beginning of the file and (an array of approximately 80 members) matched a string towards the end of the file, I had to remove three lines towards the end. The problem that happened when I didn't use a copy is that the index would reset from 30, back to 9, and this caused me some issues.

This is what worked for me.

$rowCopy = $row

foreach($row as $index => &$line) {

    ////previous code

    if ($line[0] === "NM1" && $line[1] === "77") {
        //read through the $row array and find the NM*85 string
        foreach ($rowCopy as $index2 => $lineT) {

            if ($s = strpos($lineT, "NM1*85") !== false) {
                $npiTest = explode("*", $lineT);
                if (strcmp(preg_replace("/[^0-9,.]/", "", $npiTest[9]), $line[9]) === 0) {
                    // $line = false;
                    $index--;
                    unset($row[$index + 1]);
                    $index++;
                    unset($row[$index + 1]);
                    $index++;
                    unset($row[$index + 1]);
                    $erased = $erased + 3;
                    $index++
                }
            }
        }

    }

}

Upvotes: 0

Toby Allen
Toby Allen

Reputation: 11213

There is no problem looping over it a second time, however you will get yourself and your code into a big knot if you start removing items. My suggestion would be to save a copy and modify that.

This is not ideal, but I'm not sure what you wish to do.

//Make a copy of your array
$URLCopy  = $urls1;

foreach (array_keys($urls1) as $line) {
    if (preg_match('/domain:(.*)/i', $line, $matches)) {
        $domain = $matches[1];
        foreach (array_keys($urls1) as $line2) {
            if ($url_domains[$line2] == $domain) {
                unset($URLCopy[$line2]);
            }
        }
    }
 }

Upvotes: 2

Related Questions