Set   A
last analyzed

Complexity

Total Complexity 21

Size/Duplication

Total Lines 162
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 21
eloc 30
dl 0
loc 162
rs 10
c 0
b 0
f 0

17 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A removeAll() 0 5 1
A remove() 0 3 1
A containsAll() 0 3 1
A intersection() 0 3 1
A contains() 0 3 1
A power() 0 11 3
A addAll() 0 5 1
A getIterator() 0 3 1
A cardinality() 0 3 1
A isEmpty() 0 3 1
A difference() 0 3 1
A add() 0 3 1
A toArray() 0 3 1
A sanitize() 0 5 1
A cartesian() 0 11 3
A union() 0 3 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Phpml\Math;
6
7
use ArrayIterator;
8
use IteratorAggregate;
9
10
class Set implements IteratorAggregate
11
{
12
    /**
13
     * @var string[]|int[]|float[]|bool[]
14
     */
15
    private $elements = [];
16
17
    /**
18
     * @param string[]|int[]|float[]|bool[] $elements
19
     */
20
    public function __construct(array $elements = [])
21
    {
22
        $this->elements = self::sanitize($elements);
23
    }
24
25
    /**
26
     * Creates the union of A and B.
27
     */
28
    public static function union(self $a, self $b): self
29
    {
30
        return new self(array_merge($a->toArray(), $b->toArray()));
31
    }
32
33
    /**
34
     * Creates the intersection of A and B.
35
     */
36
    public static function intersection(self $a, self $b): self
37
    {
38
        return new self(array_intersect($a->toArray(), $b->toArray()));
39
    }
40
41
    /**
42
     * Creates the difference of A and B.
43
     */
44
    public static function difference(self $a, self $b): self
45
    {
46
        return new self(array_diff($a->toArray(), $b->toArray()));
47
    }
48
49
    /**
50
     * Creates the Cartesian product of A and B.
51
     *
52
     * @return Set[]
53
     */
54
    public static function cartesian(self $a, self $b): array
55
    {
56
        $cartesian = [];
57
58
        foreach ($a as $multiplier) {
59
            foreach ($b as $multiplicand) {
60
                $cartesian[] = new self(array_merge([$multiplicand], [$multiplier]));
61
            }
62
        }
63
64
        return $cartesian;
65
    }
66
67
    /**
68
     * Creates the power set of A.
69
     *
70
     * @return Set[]
71
     */
72
    public static function power(self $a): array
73
    {
74
        $power = [new self()];
75
76
        foreach ($a as $multiplicand) {
77
            foreach ($power as $multiplier) {
78
                $power[] = new self(array_merge([$multiplicand], $multiplier->toArray()));
79
            }
80
        }
81
82
        return $power;
83
    }
84
85
    /**
86
     * @param string|int|float|bool $element
87
     */
88
    public function add($element): self
89
    {
90
        return $this->addAll([$element]);
91
    }
92
93
    /**
94
     * @param string[]|int[]|float[]|bool[] $elements
95
     */
96
    public function addAll(array $elements): self
97
    {
98
        $this->elements = self::sanitize(array_merge($this->elements, $elements));
99
100
        return $this;
101
    }
102
103
    /**
104
     * @param string|int|float $element
105
     */
106
    public function remove($element): self
107
    {
108
        return $this->removeAll([$element]);
109
    }
110
111
    /**
112
     * @param string[]|int[]|float[] $elements
113
     */
114
    public function removeAll(array $elements): self
115
    {
116
        $this->elements = self::sanitize(array_diff($this->elements, $elements));
117
118
        return $this;
119
    }
120
121
    /**
122
     * @param string|int|float $element
123
     */
124
    public function contains($element): bool
125
    {
126
        return $this->containsAll([$element]);
127
    }
128
129
    /**
130
     * @param string[]|int[]|float[] $elements
131
     */
132
    public function containsAll(array $elements): bool
133
    {
134
        return count(array_diff($elements, $this->elements)) === 0;
135
    }
136
137
    /**
138
     * @return string[]|int[]|float[]|bool[]
139
     */
140
    public function toArray(): array
141
    {
142
        return $this->elements;
143
    }
144
145
    public function getIterator(): ArrayIterator
146
    {
147
        return new ArrayIterator($this->elements);
148
    }
149
150
    public function isEmpty(): bool
151
    {
152
        return $this->cardinality() === 0;
153
    }
154
155
    public function cardinality(): int
156
    {
157
        return count($this->elements);
158
    }
159
160
    /**
161
     * Removes duplicates and rewrites index.
162
     *
163
     * @param string[]|int[]|float[]|bool[] $elements
164
     *
165
     * @return string[]|int[]|float[]|bool[]
166
     */
167
    private static function sanitize(array $elements): array
168
    {
169
        sort($elements, SORT_ASC);
170
171
        return array_values(array_unique($elements, SORT_ASC));
172
    }
173
}
174