Split::__invoke()   B
last analyzed

Complexity

Conditions 9
Paths 1

Size

Total Lines 50
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 22
CRAP Score 9

Importance

Changes 0
Metric Value
cc 9
eloc 21
nc 1
nop 0
dl 0
loc 50
ccs 22
cts 22
cp 1
crap 9
rs 8.0555
c 0
b 0
f 0
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\Contract\Operation\Splitable;
10
use loophp\collection\Utils\CallbacksArrayReducer;
11
12
/**
13
 * @immutable
14
 *
15
 * @template TKey
16
 * @template T
17
 */
18
final class Split extends AbstractOperation
19
{
20
    /**
21
     * @return Closure(int): Closure((callable(T, TKey): bool)...): Closure(iterable<TKey, T>): Generator<int, list<T>>
22
     */
23 12
    public function __invoke(): Closure
24
    {
25 12
        return
26
            /**
27
             * @return Closure((callable(T, TKey): bool)...): Closure(iterable<TKey, T>): Generator<int, list<T>>
28
             */
29 12
            static fn (int $type = Splitable::BEFORE): Closure =>
30
                /**
31
                 * @param callable(T, TKey): bool ...$callbacks
32
                 *
33
                 * @return Closure(iterable<TKey, T>): Generator<int, list<T>>
34
                 */
35 12
                static fn (callable ...$callbacks): Closure =>
36
                    /**
37
                     * @param iterable<TKey, T> $iterable
38
                     *
39
                     * @return Generator<int, list<T>>
40
                     */
41 12
                    static function (iterable $iterable) use ($type, $callbacks): Generator {
42 12
                        $carry = [];
43 12
                        $callback = CallbacksArrayReducer::or()($callbacks);
44
45 12
                        foreach ($iterable as $key => $current) {
46 12
                            $callbackReturn = $callback($current, $key, $iterable);
47
48 12
                            if (Splitable::AFTER === $type) {
49 2
                                $carry[] = $current;
50
                            }
51
52 12
                            if ($callbackReturn && (Splitable::REMOVE === $type)) {
53 8
                                yield $carry;
54
55 8
                                $carry = [];
56
57 8
                                continue;
58
                            }
59
60 12
                            if ($callbackReturn && ([] !== $carry)) {
61 4
                                yield $carry;
62
63 4
                                $carry = [];
64
                            }
65
66 12
                            if (Splitable::AFTER !== $type) {
67 10
                                $carry[] = $current;
68
                            }
69
                        }
70
71 12
                        if ([] !== $carry) {
72 12
                            yield $carry;
73
                        }
74 12
                    };
75
    }
76
}
77