Home > Software engineering >  PHP unset not removing value from array loop
PHP unset not removing value from array loop

Time:11-08

I have an array("https", "www", "stackoverflow", "com")

$search_array = array("https", "www", "stackoverflow", "com");

for ($i=0; $i < count($search_array); $i  ) { 
    if (
        $search_array[$i] == null ||
        strtolower($search_array[$i]) == "http" && count($search_array) > 1 ||
        strtolower($search_array[$i]) == "https" && count($search_array) > 1 ||
        strtolower($search_array[$i]) == "www" && count($search_array) > 1 ||
        strtolower($search_array[$i]) == "com" && count($search_array) > 1
    ) unset($search_array[$i]);
}

die(print_r($search_array));

I want the result array("stackoverflow");, but im getting the result array("stackoverflow", "com"); any idea?

CodePudding user response:

As pointed out in the comments and other answers, you have an issue when looping and unset()-ing. The answers show how to handle this when using a for() loop, but you can also simply use a foreach():

$search_array = array("https", "www", "stackoverflow", "com");

foreach($search_array as $i => $domain) { 
    if (
        $domain == null ||
        $domain == "http" && count($search_array) > 1 ||
        $domain == "https" && count($search_array) > 1 ||
        $domain == "www" && count($search_array) > 1 ||
        $domain == "com" && count($search_array) > 1
    ) { 
        unset($search_array[$i]);
    }
}

die(print_r($search_array));

Output from this approach is:

Array ( [2] => stackoverflow )

CodePudding user response:

You are modifying the array while looping around it. This causes the for loop to not run for all of the elements inside it. You can verify this by calling echo $i where you currently do unset().

Also your if statements need brackets around them to ensure that the && and || run in the correct order.

To get the result you want, create a new array of the valid values that you want to save:

<?php
$search_array = array("https", "www", "stackoverflow", "com");
$result_array = array();

for ($i = 0; $i < count($search_array); $i  ) {
    $item = strtolower($search_array[$i]);
    
    if (
        isset($search_array[$i])
        && $item !== "http"
        && $item !== "https"
        && $item !== "www"
        && $item !== "com"
    ) {
        $result_array[] = $item;
    }
}


var_dump($result_array);   // Result => "stackoverflow"

CodePudding user response:

You're changing the value of your loop exit condition inside your loop - which is usually a bad idea. On unsetting the array value, the array length gets lower, and thus the last iteration is never run.

first run (after unset): $i=0; $search_array = array("www", "stackoverflow", "com"); count($search_array)=3

second run (after unset): $i=1; $search_array = array("stackoverflow", "com"); count($search_array)=2

now your loop won't run again, as next $i would be 2, and this is now triggering your exit condition...

CodePudding user response:

In addition to what others here correctly point out and demonstrate I would like to suggest to take a somewhat more direct approach: always use the right tool for your task.

What you are trying to do is filter the input array, right? Then why don't you use the array_filter() function which does exactly that?

<?php
print_r(
    array_filter(
        ["https", "www", "stackoverflow", "com"], 
        function($value) {
            return !in_array($value, ["https", "www", "com"]);
        }
    )
);

The output obviously is:

Array ( [2] => stackoverflow )

CodePudding user response:

Think I might be late, but this is happening because you were modifying the original array. A much more cleaner way of doing this would be as follows:

<?php

$search_array = array("https", "www", "stackoverflow", "com");

for ($i=count($search_array)-1; $i>=0; $i--) { 
    if ( in_array(strtolower($search_array[$i]), ["https", "www", "com"]) )
        unset($search_array[$i]);
}

echo print_r($search_array, true);
  • Related