Passed
Push — master ( dad483...8852ad )
by Stephen
02:13
created

ChunkSizer::execute()   B

Complexity

Conditions 8
Paths 6

Size

Total Lines 38
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 8
eloc 18
c 1
b 0
f 0
nc 6
nop 4
dl 0
loc 38
rs 8.4444
1
<?php
2
3
4
namespace Sfneal\Helpers\Arrays;
5
6
7
use Sfneal\Actions\AbstractActionStatic;
8
9
class ChunkSizer extends AbstractActionStatic
10
{
11
    /**
12
     * Return a best fit chunk size to be passed to array_chunks functions.
13
     *
14
     * Calculates the remainder of array sizes divided by the divisor
15
     * using modulus division.  Continues to calculate remainders until
16
     * the remainder is zero, signifying evenly sized chunks, or the
17
     * divisor is equal to the array size.  If a remainder of zero is not
18
     * found the lowest remainder is returned.
19
     *
20
     * @param int $array_size
21
     * @param int $min minimum chunk size
22
     * @param null $max maximum chunk size
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $max is correct as it would always require null to be passed?
Loading history...
23
     * @param int $divisor
24
     * @return int $remainder lowest calculated remainder
25
     */
26
    public static function execute(int $array_size, $min = 0, $max = null, $divisor = 2): int
27
    {
28
        // If the size of the array is a perfect square, return the square root
29
        if (gmp_perfect_square($array_size) == true) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
30
            return sqrt($array_size);
31
        }
32
33
        // If min and max are the same return that value
34
        elseif ($min == $max) {
35
            return $min;
36
        }
37
38
        $max = (isset($max) ? $max : $array_size);
39
        $sizes = [];
40
        while ($divisor < $max) {
41
            $sizes[$divisor] = [
42
                // Number of chunks
43
                'rows'=> floor($array_size / $divisor),
44
45
                // Items in each chunk
46
                'cols' => $divisor,
47
48
                // Left over items in last chunk
49
                'remainder' => $array_size % $divisor,
50
            ];
51
            $divisor++;
52
        }
53
54
        // Filter sizes by column values
55
        return min(array_filter(
56
            array_column($sizes, 'cols', 'cols'),
57
            function ($size) use ($min, $max, $sizes) {
58
                return
59
                    // Check that the remainder is no more than half of the number of columns
60
                    ($sizes[$size]['remainder'] == 0 || $sizes[$size]['remainder'] >= $size / 2) &&
61
62
                    // Check that the number of columns is greater than or equal than min and less than or equal than max
63
                    $min <= $size && $size <= $max;
64
            }
65
        ));
66
    }
67
}
68