Accumulators   A
last analyzed

Complexity

Total Complexity 4

Size/Duplication

Total Lines 107
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 17
c 1
b 0
f 0
dl 0
loc 107
ccs 12
cts 12
cp 1
rs 10
wmc 4

17 Methods

Rating   Name   Duplication   Size   Complexity  
A hp$2 ➔ initial() 0 1 1
A hp$3 ➔ initial() 0 1 1
A hp$1 ➔ __invoke() 0 1 1
A hp$0 ➔ initial() 0 1 1
A hp$2 ➔ __invoke() 0 1 2
A hp$3 ➔ __invoke() 0 1 2
A hp$1 ➔ initial() 0 1 1
A hp$0 ➔ __invoke() 0 1 1
A __construct() 0 1 1
A hp$0 ➔ sum() 0 9 1
max() 0 9 ?
A hp$3 ➔ max() 0 9 1
A hp$1 ➔ multiply() 0 9 1
min() 0 9 ?
multiply() 0 9 ?
sum() 0 9 ?
A hp$2 ➔ min() 0 9 1
1
<?php
2
3
namespace Bdf\Collection\Stream\Accumulator;
4
5
use Bdf\Collection\Stream\StreamInterface;
6
7
/**
8
 * Base accumulators for perform standard reduce operations on streams
9
 *
10
 * @see AccumulatorInterface
11
 * @see StreamInterface::reduce()
12
 */
13
final class Accumulators
14
{
15
    /** @var AccumulatorInterface|null */
16
    private static $sum;
17
    /** @var AccumulatorInterface|null */
18
    private static $multiply;
19
    /** @var AccumulatorInterface|null */
20
    private static $min;
21
    /** @var AccumulatorInterface|null */
22
    private static $max;
23
24
    /** Deny instantiation */
25
    private function __construct() { }
26
27
    /**
28
     * Perform a sum on each elements of the stream
29
     *
30
     * <code>
31
     * $stream = new ArrayStream([1, 2, 3]);
32
     * $stream->reduce(Accumulators::sum()); // 6
33
     * </code>
34
     *
35
     * @template V as numeric
36
     *
37
     * @return AccumulatorInterface<V, V>
38
     */
39 19
    public static function sum()
40
    {
41 19
        if (self::$sum) {
42 19
            return self::$sum;
43
        }
44
45
        return self::$sum = new class implements AccumulatorInterface {
46
            public function __invoke($carry, $item) { return $carry + $item; }
47
            public function initial() { return 0; }
0 ignored issues
show
Bug Best Practice introduced by
The expression return 0 returns the type integer which is incompatible with the return type mandated by Bdf\Collection\Stream\Ac...torInterface::initial() of Bdf\Collection\Stream\Accumulator\V.

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
48
        };
49
    }
50
51
    /**
52
     * Perform a multiplication on each elements of the stream
53
     *
54
     * <code>
55
     * $stream = new ArrayStream([2, 5, 4]);
56
     * $stream->reduce(Accumulators::multiply()); // 80
57
     * </code>
58
     *
59
     * @template V as numeric
60
     *
61
     * @return AccumulatorInterface<V, V>
62
     */
63 2
    public static function multiply()
64
    {
65 2
        if (self::$multiply) {
66 2
            return self::$multiply;
67
        }
68
69
        return self::$multiply = new class implements AccumulatorInterface {
70
            public function __invoke($carry, $item) { return $carry * $item; }
0 ignored issues
show
Bug Best Practice introduced by
The expression return $carry * $item returns the type integer which is incompatible with the return type mandated by Bdf\Collection\Stream\Ac...orInterface::__invoke() of Bdf\Collection\Stream\Accumulator\R.

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
71
            public function initial() { return 1; }
0 ignored issues
show
Bug Best Practice introduced by
The expression return 1 returns the type integer which is incompatible with the return type mandated by Bdf\Collection\Stream\Ac...torInterface::initial() of Bdf\Collection\Stream\Accumulator\V.

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
72
        };
73
    }
74
75
    /**
76
     * Get the lowest element of the stream
77
     *
78
     * <code>
79
     * $stream = new ArrayStream([8, 5, 4]);
80
     * $stream->reduce(Accumulators::min()); // 4
81
     * </code>
82
     *
83
     * @template V
84
     *
85
     * @return AccumulatorInterface<V, V>
86
     */
87 2
    public static function min()
88
    {
89 2
        if (self::$min) {
90 2
            return self::$min;
91
        }
92
93
        return self::$min = new class implements AccumulatorInterface {
94
            public function __invoke($carry, $item) { return $item < $carry ? $item : $carry; }
95
            public function initial() { return PHP_INT_MAX; }
0 ignored issues
show
Bug Best Practice introduced by
The expression return Bdf\Collection\St...Accumulator\PHP_INT_MAX returns the type integer which is incompatible with the return type mandated by Bdf\Collection\Stream\Ac...torInterface::initial() of Bdf\Collection\Stream\Accumulator\V.

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
96
        };
97
    }
98
99
    /**
100
     * Get the highest element of the stream
101
     *
102
     * <code>
103
     * $stream = new ArrayStream([4, 8, 2]);
104
     * $stream->reduce(Accumulators::max()); // 8
105
     * </code>
106
     *
107
     * @template V as numeric
108
     *
109
     * @return AccumulatorInterface<V, V>
110
     */
111 2
    public static function max()
112
    {
113 2
        if (self::$max) {
114 2
            return self::$max;
115
        }
116
117
        return self::$max = new class implements AccumulatorInterface {
118
            public function __invoke($carry, $item) { return $item > $carry ? $item : $carry; }
119
            public function initial() { return PHP_INT_MIN; }
120
        };
121
    }
122
}
123