ArrayReduceAggregator::setAggregateFunction()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 4
rs 10
c 1
b 0
f 0
1
<?php
2
3
4
namespace Vctls\IntervalGraph;
5
6
7
use Closure;
8
9
/**
10
 * Aggregate values through `array_reduce`.
11
 *
12
 * @package Vctls\IntervalGraph
13
 */
14
class ArrayReduceAggregator implements AggregatorInterface
15
{
16
    /** @var Closure Aggregate interval values. */
17
    protected $aggregateFunction;
18
19
    /**
20
     * @return Closure
21
     */
22
    public function getAggregateFunction(): Closure
23
    {
24
        return $this->aggregateFunction;
25
    }
26
27
    /**
28
     * Define the function to aggregate interval values.
29
     *
30
     * @param Closure $aggregate
31
     * @return ArrayReduceAggregator
32
     */
33
    public function setAggregateFunction(Closure $aggregate): AggregatorInterface
34
    {
35
        $this->aggregateFunction = $aggregate;
36
        return $this;
37
    }
38
39
    public function __construct()
40
    {
41
        $this->aggregateFunction = static function ($a, $b) {
42
            if ($a === null && $b === null) {
43
                return null;
44
            }
45
            return round($a + $b, 2);
46
        };
47
    }
48
49
    /**
50
     * Walk through an array of adjacent intervals, and compute the aggregated values
51
     * from the values of the corresponding original intervals.
52
     *
53
     * @param array $adjacentIntervals
54
     * @param array $originalIntervals
55
     * @return array
56
     */
57
    public function aggregate(array $adjacentIntervals, array $originalIntervals): array
58
    {
59
        $originalValues = [];
60
61
        // Get the values of the original intervals, including nulls.
62
        foreach ($originalIntervals as $i => $interval) {
63
            $originalValues[$i] = $interval[2] ?? null;
64
        }
65
66
        // If no intervals are active on this bound,
67
        // the value of this interval is null.
68
        // Else, aggregate the values of the corresponding intervals.
69
        foreach ($adjacentIntervals as $key => $adjacentInterval) {
70
            if (empty($adjacentInterval[2])) {
71
                $adjacentIntervals[$key][2] = null;
72
            } else {
73
                $adjacentIntervals[$key][2] = array_reduce(
74
                    array_intersect_key($originalValues, $adjacentInterval[2]),
75
                    $this->aggregateFunction
76
                );
77
            }
78
        }
79
        return $adjacentIntervals;
80
    }
81
}
82