1

Given this working code:

$input_array = array(
    "192.168.1.100",
    "192.168.1.101",
    "192.168.1.100",
    "192.168.1.102",
    "192.168.1.103",
    "192.168.1.198",
    "192.168.1.101",
    "192.168.1.25",
    "192.168.1.109",
    "192.168.1.109",
    "192.168.1.109",
    "192.168.1.100",
    "192.168.1.58"
);

$final_array = array();

foreach ($input_array as $value) {
    //if the value is present more or eq 3 times
    if (count(array_keys($input_array, $value)) >= 3) {

        //Add it to final array
        $final_array[] = $value;

        //Echo in the console
        echo "IP $value  will be banned!" . PHP_EOL;

        //Clean up the input array
        foreach ($input_array as $k => $v) {
            if ($value == $v) {
                unset($input_array[$k]);
            }
        }
    }
} 

How would you optimize the "Clean up the input array" phase? Is there a way to delete all the items in the input array those matches the if condition?

Thanks everyone

2 Answers 2

2

You can use array_count_values with array_filter too like:

$input_array = array(
    "192.168.1.100",
    "192.168.1.101",
    "192.168.1.100",
    "192.168.1.102",
    "192.168.1.103",
    "192.168.1.198",
    "192.168.1.101",
    "192.168.1.25",
    "192.168.1.109",
    "192.168.1.109",
    "192.168.1.109",
    "192.168.1.100",
    "192.168.1.58"
);
$ipsCount = array_count_values($input_array);
$final_array = array_filter($input_array, function($val) use($ipsCount) {
    if($ipsCount[$val] >= 3){
        echo "IP $val  will be banned!" . PHP_EOL;
        return $val;
    }
});
print_r($final_array);

Reference:


You can extend same method for find value < 3

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

1 Comment

I will deepen this solution, very cool!
1

Yes, add a key to the initial foreach and use it to unset the value in the input array you are adding to the ban list.

$input_array = array( "192.168.1.100", "192.168.1.101", "192.168.1.100", 
                        "192.168.1.102", "192.168.1.103", "192.168.1.198", 
                        "192.168.1.101", "192.168.1.25", "192.168.1.109", 
                        "192.168.1.109", "192.168.1.109", "192.168.1.100", 
                        "192.168.1.58") ;

$final_array = array();

$counted = array_count_values($input_array);
arsort($counted);   //get the big numbers first
foreach( $counted as $ip=>$cnt ){
    if ( $cnt >= 3 ) {
        $final_array[] = $ip;
        echo "IP $ip  will be banned!" . PHP_EOL;
    } else {
        break;  // stop unnecessary loops once we processed all the >= 3's
    }
}
//tidy the input array
$input_array = array_values(array_diff($input_array,$final_array));

2 Comments

Ok, this actually works. I don't get why it is working btw. The key 0 will be the first to be unset by unset($input_array[0]) because the first IP is listed 3 times in the array. But how can unset($input_array[0]) delete also key 2 and key 11?
Actually it didn't work when I looked closer! So I rewrote it, seems abit like the other answer now, purely a coinsidence, I didnt see that untill I posted this correction

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.