Entropy::__invoke()   A
last analyzed

Complexity

Conditions 5
Paths 1

Size

Total Lines 39
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 24
CRAP Score 5

Importance

Changes 2
Bugs 0 Features 1
Metric Value
cc 5
eloc 16
c 2
b 0
f 1
nc 1
nop 0
dl 0
loc 39
ccs 24
cts 24
cp 1
crap 5
rs 9.4222
1
<?php
2
3
declare(strict_types=1);
4
5
namespace loophp\collection\Operation;
6
7
use Closure;
8
use Generator;
9
use loophp\collection\Collection;
10
11
/**
12
 * @immutable
13
 *
14
 * @template TKey
15
 * @template T
16
 */
17
final class Entropy extends AbstractOperation
18
{
19
    /**
20
     * @return Closure(iterable<TKey, T>): Generator<int, int<0,1>|float>
21
     */
22 4
    public function __invoke(): Closure
23
    {
24
        /** @var Closure(iterable<TKey, T>): Generator<int, int<0,1>|float> $pipe */
25 4
        $pipe = (new Pipe())()(
26 4
            (new Map())()(
27
                /**
28
                 * @param T $_
29
                 * @param iterable<TKey, T> $iterable
30
                 */
31 4
                static function (mixed $_, int $key, iterable $iterable): float {
32 3
                    $collection = Collection::fromIterable($iterable);
33
34 3
                    return $collection
0 ignored issues
show
Bug Best Practice introduced by
The expression return $collection->norm...(...) { /* ... */ }, 0) returns the type loophp\collection\Contract\Operation\V which is incompatible with the type-hinted return double.
Loading history...
35 3
                        ->normalize()
36 3
                        ->squash()
37 3
                        ->limit($key + 1)
38 3
                        ->frequency()
39 3
                        ->map(
40
                            /**
41
                             * @param T $_
42
                             */
43 3
                            static fn (mixed $_, int $freq): float => $freq / ($key + 1)
44 3
                        )
45 3
                        ->reduce(
46 3
                            static fn (float $acc, float $p, int $k): float => 0 === $key ? $acc : $acc - $p * log($p, 2) / ((1 === $k) ? 1 : log($k, 2)),
47 3
                            0
48 3
                        );
49 4
                }
50 4
            ),
51 4
            (new Map())()(
52
                /**
53
                 * @return int<0,1>|float
54
                 */
55 4
                static fn (float $value): float|int => (0.0 === $value || 1.0 === $value) ? (int) $value : $value
0 ignored issues
show
introduced by
The condition 1.0 === $value is always false.
Loading history...
56 4
            )
57 4
        );
58
59
        // Point free style
60 4
        return $pipe;
61
    }
62
}
63