serese
serese

Reputation: 33

Count in array and Exception

I have an example array:

$array = [
    [
        FirstClass,
        SecondClass,
        ThirdClass,
    ],
    [
        ThirdClass,
        MaxClass
    ],
    [
        FirstClass,
        ThirdClass
    ],
    [
        SecondClass,
        FirstClass,
    ]
];

I would like to check if MaxClass exists and additionally throw an error if there is more than one.

So I do:

foreach ($array as $class) {
    if (get_class($class) == 'MaxClass') {
        //different operations
    }
}

For checking I'm adding:

$count = 0;
foreach ($array as $class) {
    if (get_class($class) == 'MaxClass') {
        if ($count < 2) {
        //different operations
        } else {
            throw new Exception('Too many MaxClass!');
        }
    }
}

But maybe is better way than using variable $count?

Second question - what Exception class should I use? Maybe RuntimeException?

Upvotes: 3

Views: 75

Answers (4)

Viktar Pryshchepa
Viktar Pryshchepa

Reputation: 343

$restrictions = [MaxClass::class => ['max' => 1, 'found' => 0]];

foreach($array as $subArray) {
    foreach($subArray as $element) {
        $className = get_class($element);

        if (isset($restrictions[$className]) {
            if ($restrictions[$className]['found'] >= $restrictions[$className]['max']) {
                // throw your exception
            }

            $restrictions[$className]['found'] += 1;
        }

        // code
    } 
}

Upvotes: 1

deceze
deceze

Reputation: 522635

I'd go for something like this with a functional approach:

class ReachedMaxLimitException extends LogicException {}

$count = array_reduce(
    call_user_func_array('array_merge', $array),  // flatten array
    function ($count, $o) { return $count + ($o instanceof MaxClass); }, 
    0
);

if ($count > 1) {
    raise new ReachedMaxLimitException;
}

Obviously that divorces the sanity check from your "// different operations", but that's also exactly the point.

Upvotes: 1

caramba
caramba

Reputation: 22490

<?php

$array = [
    [
        "FirstClass",
        "SecondClass",
        "ThirdClass",
    ],
    [
        "ThirdClass",
        "MaxClass"
    ],
    [
        "FirstClass",
        "ThirdClass"
    ],
    [
        "SecondClass",
        "FirstClass",
        "MaxClass"
    ]
];

$countValues = array_count_values(array_reduce($array, 'array_merge', array()));

var_dump($countValues["MaxClass"]);

if($countValues["MaxClass"] > 1) {
    throw new Exception('Too many MaxClass!');
}

see example here: http://sandbox.onlinephpfunctions.com/code/9a27d9388b93c4ac4903891517dc8ad531f04a94

Upvotes: 1

B. Desai
B. Desai

Reputation: 16436

You can use flag variable to check : Try this solution :

$found_max_class=false;
foreach ($array as $class) {
    if (get_class($class) == 'MaxClass') {
       if($found_max_class)
        {
            throw new Exception('Too many MaxClass!');
        }
        $found_max_class =true;
    }
}

Upvotes: 3

Related Questions