0

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?

12
  • What have you tried to resolve the problem? Where are you stuck? That's so little code that you should be able to dump the values in each iteration and check them Commented Nov 7, 2022 at 16:51
  • @NicoHaase Its not removing the "com" from the array even tho i belive the code is correct? Commented Nov 7, 2022 at 16:52
  • 1
    This isn't a solution per-se, but your code works perfect when using a foreach() instead of a for() loop: foreach($search_array as $i => $domain) { (3v4l.org/41FYo for reference) Commented Nov 7, 2022 at 16:55
  • 1
    @TimLewis i have realised its down to the count($search_array), the count will go down in each for loop. thanks Commented Nov 7, 2022 at 16:59
  • 1
    Yeah exactly, the count goes down and iteration stops. $c = count($search_array); for ($i=0; $i < $c; $i++) {. Just do the count before the loop. (Also, in general a good idea to avoid functions in a loop condition, waste of cycles to re-evaluate at each loop.) Commented Nov 7, 2022 at 17:02

5 Answers 5

1

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 )

Sign up to request clarification or add additional context in comments.

Comments

1

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"

Comments

1

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...

Comments

1

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 )

2 Comments

Would array_diff() be a better tool?
@NigelRen Also an alternative, there is no yes or no for that. It depends on the actual task the OP faces. The code in the OPs question obviously is just a demonstration, not the real task. array_filter() offers much more flexibility. Just think of case insensivity and trimming for example.
0

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);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.