Completed
Push — master ( cb5f1c...5f5111 )
by Victor
03:46
created

Flattener::calcAdjacentIntervals()   B

Complexity

Conditions 11
Paths 9

Size

Total Lines 52
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 11
eloc 27
c 1
b 0
f 0
nc 9
nop 1
dl 0
loc 52
rs 7.3166

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Vctls\IntervalGraph;
4
5
use Closure;
6
7
/**
8
 * Transforms an array of overlapping intervals into another array of adjacent intervals.
9
 *
10
 * Each new interval holds the keys of the corresponding original intervals.
11
 *
12
 * @package Vctls\IntervalGraph
13
 */
14
class Flattener
15
{
16
    /** @var Closure Substract one step from a bound value. */
17
    protected $substractStep;
18
19
    /** @var Closure Add one step to the bound value. */
20
    protected $addStep;
21
22
    /**
23
     * Set the Closure for decrementing bound values when dealing with
24
     * discontinuous sets.
25
     *
26
     * @param Closure $substractStep
27
     * @return Flattener
28
     */
29
    public function setSubstractStep(Closure $substractStep): Flattener
30
    {
31
        $this->substractStep = $substractStep;
32
        return $this;
33
    }
34
35
    /**
36
     * Set the Closure for incrementing bound values when dealing with
37
     * discontinuous sets.
38
     *
39
     * @param Closure $addStep
40
     * @return Flattener
41
     */
42
    public function setAddStep(Closure $addStep): Flattener
43
    {
44
        $this->addStep = $addStep;
45
        return $this;
46
    }
47
48
    /**
49
     * Create each new interval and calculate its value based on the active intervals on each bound.
50
     *
51
     * @param array $bounds
52
     * @return array
53
     */
54
    public function calcAdjacentIntervals(array $bounds): array
55
    {
56
57
        $newIntervals = [];
58
        $activeIntervals = [];
59
60
        $boundsCount = count($bounds);
61
62
        // Create new intervals for each set of two consecutive bounds,
63
        // and calculate its total value.
64
        for ($i = 1; $i < $boundsCount; $i++) {
65
66
            // Set the current bound.
67
            [$curBoundValue, $curBoundType, $curBoundIncluded, $curBoundIntervalKey] = $bounds[$i - 1];
68
            [$nextBoundValue, $nextBoundType, $nextBoundIncluded] = $bounds[$i];
69
70
            if ($curBoundType === '+') {
71
                // If this is a low bound,
72
                // add the key of the interval to the array of active intervals.
73
                $activeIntervals[$curBoundIntervalKey] = true;
74
            } else {
75
                // If this is an high bound, remove the key.
76
                unset($activeIntervals[$curBoundIntervalKey]);
77
            }
78
79
            if (
80
                isset($this->addStep, $this->substractStep) && (
81
                    ($nextBoundIncluded && $nextBoundType === '+')
82
                    || (!$nextBoundIncluded && $nextBoundType === '+')
83
                )
84
            ) {
85
                $newHighBound = ($this->substractStep)($nextBoundValue);
86
            } else {
87
                $newHighBound = $nextBoundValue;
88
            }
89
90
            if (
91
                isset($this->addStep, $this->substractStep) && $curBoundType === '-' && $curBoundIncluded
92
            ) {
93
                $newLowBound = ($this->addStep)($curBoundValue);
94
            } else {
95
                $newLowBound = $curBoundValue;
96
            }
97
98
            $newIntervals[] = [
99
                $newLowBound,
100
                $newHighBound,
101
                $activeIntervals
102
            ];
103
        }
104
105
        return $newIntervals;
106
    }
107
}
108