ArrayMaskView   A
last analyzed

Complexity

Total Complexity 3

Size/Duplication

Total Lines 31
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 3
eloc 10
c 1
b 0
f 0
dl 0
loc 31
rs 10

1 Method

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 13 3
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Smoren\ArrayView\Views;
6
7
use Smoren\ArrayView\Exceptions\ReadonlyError;
8
use Smoren\ArrayView\Exceptions\SizeError;
9
use Smoren\ArrayView\Exceptions\ValueError;
10
use Smoren\ArrayView\Interfaces\ArrayViewInterface;
11
12
/**
13
 * Class representing a mask-based view of an array or another ArrayView for accessing elements based on a boolean mask.
14
 *
15
 * Each element in the view is included or excluded based on the specified boolean mask.
16
 *
17
 * ```php
18
 * $source = [1, 2, 3, 4, 5];
19
 * $view = ArrayView::toView($source)->subview(new MaskSelector([true, false, true, false, true]));
20
 * $view->toArray(); // [1, 3, 5]
21
 * ```
22
 *
23
 * @template T Type of array source elements.
24
 *
25
 * @extends ArrayIndexListView<T>
26
 */
27
class ArrayMaskView extends ArrayIndexListView
28
{
29
    /**
30
     * @var array<bool> The boolean mask specifying whether each element in the source array
31
     * should be included in the view (true) or excluded (false).
32
     */
33
    protected array $mask;
34
35
    /**
36
     * Constructs a new ArrayMaskView instance with the specified source array or ArrayView and boolean mask.
37
     *
38
     * @param array<T>|ArrayViewInterface<T> $source The source array or ArrayView to create a view from.
39
     * @param array<bool> $mask Options for configuring the view.
40
     * @param bool|null $readonly The boolean mask for including or excluding elements from the source array.
41
     *
42
     * @throws ValueError if the array is not sequential.
43
     * @throws ReadonlyError if the source is readonly and trying to create a non-readonly view.
44
     */
45
    public function __construct(&$source, array $mask, ?bool $readonly = null)
46
    {
47
        [$sourceSize, $maskSize] = [\count($source), \count($mask)];
48
        if ($sourceSize !== $maskSize) {
49
            throw new SizeError("Mask size not equal to source length ({$maskSize} != {$sourceSize}).");
50
        }
51
52
        $indexes = array_filter(
53
            array_map(fn (bool $v, int $i) => $v ? $i : null, $mask, array_keys($mask)),
54
            fn ($v) => $v !== null
55
        );
56
        parent::__construct($source, array_values($indexes), $readonly);
57
        $this->mask = $mask;
58
    }
59
}
60