Passed
Branch version-4 (8b03a3)
by Sebastian
02:18
created

MapTrait::containsKey()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
1
<?php
2
declare(strict_types=1);
3
/*
4
 * Copyright (C) 2022 Sebastian Böttger <[email protected]>
5
 * You may use, distribute and modify this code under the
6
 * terms of the MIT license.
7
 *
8
 * You should have received a copy of the MIT license with
9
 * this file. If not, please visit: https://opensource.org/licenses/mit-license.php
10
 */
11
12
namespace Seboettg\Collection\Map;
13
14
use ArrayIterator;
15
use Iterator;
16
use ReflectionException;
17
use ReflectionFunction;
18
use Seboettg\Collection\Assert\Exception\NotApplicableCallableException;
19
use Seboettg\Collection\Lists;
20
use Seboettg\Collection\Lists\ArrayListTrait;
21
use Seboettg\Collection\Lists\ListInterface;
22
use Seboettg\Collection\Map;
23
use Seboettg\Collection\NativePhp\ArrayAccessTrait;
24
use function Seboettg\Collection\Assert\assertScalar;
25
use function Seboettg\Collection\Assert\assertValidCallable;
26
use function Seboettg\Collection\Lists\emptyList;
27
use function Seboettg\Collection\Lists\listOf;
28
29
/**
30
 * @property array $array base array of this data structure
31
 */
32
trait MapTrait
33
{
34
    use ArrayAccessTrait;
35
36
    /**
37
     * @inheritDoc
38
     */
39 1
    public function getEntries(): ListInterface
40
    {
41
        return listOf(...array_map(function (string $key, $value) {
42 1
            return pair($key, $value);
43 1
        }, array_keys($this->array), $this->array));
44
45
    }
0 ignored issues
show
Coding Style introduced by
Function closing brace must go on the next line following the body; found 1 blank lines before brace
Loading history...
46
47
    /**
48
     * @inheritDoc
49
     */
50 1
    public function getKeys(): ListInterface
51
    {
52 1
        return listOf(...array_keys($this->array));
53
    }
54
55
    /**
56
     * @inheritDoc
57
     */
58 1
    public function values(): ListInterface
59
    {
60 1
        return listOf(...array_values($this->array));
61
    }
62
63
    /**
64
     * {@inheritDoc}
65
     */
66 8
    public function count(): int
67
    {
68 8
        return count($this->array);
69
    }
70
71
    /**
72
     * @inheritDoc
73
     */
74 1
    public function size(): int
75
    {
76 1
        return $this->count();
77
    }
78
79
    /**
80
     * @inheritDoc
81
     */
82
    public function clear(): void
83
    {
84
        unset($this->array);
85
        $this->array = [];
86
    }
87
88
    /**
89
     * @inheritDoc
90
     * @param scalar $key
91
     * @return bool
92
     */
93 6
    public function contains($key): bool
94
    {
95 6
        assertScalar($key, "Key must be a scalar value");
96 4
        return array_key_exists($key, $this->array);
97
    }
98
99
    /**
100
     * @inheritDoc
101
     * @param array $array
102
     */
103
    public function setArray(array $array): void
104
    {
105
        $this->array = $array;
106
    }
107
108
    /**
109
     * @inheritDoc
110
     * @param scalar
111
     * @return string
112
     */
113 1
    public function containsKey($key): bool
114
    {
115 1
        return $this->contains($key);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->contains($key) returns the type boolean which is incompatible with the documented return type string.
Loading history...
116
    }
117
118
    /**
119
     * @inheritDoc
120
     * @param mixed $value
121
     * @return bool
122
     */
123
    public function containsValue($value): bool
124
    {
125
        return in_array($value, $this->array, true) !== false;
126
    }
127
128
    /**
129
     * @inheritDoc
130
     * @return bool
131
     */
132 2
    public function isEmpty(): bool
133
    {
134 2
        return $this->count() === 0;
135
    }
136
137
    /**
138
     * @inheritDoc
139
     * @param scalar
140
     * @return mixed
141
     */
142 5
    public function get($key)
143
    {
144 5
        return $this->array[$key] ?? null;
145
    }
146
147
    /**
148
     * @inheritDoc
149
     * @param scalar $key
150
     * @param mixed $value
151
     */
152 22
    public function put($key, $value): void
153
    {
154 22
        assertScalar($key, "Key must be a scalar value");
155 22
        $this->array[$key] = $value;
156 22
    }
157
158
    /**
159
     * @param MapInterface<scalar, mixed> $map
160
     * @return void
161
     */
162 1
    public function putAll(MapInterface $map): void
163
    {
164 1
        foreach ($map as $key => $value) {
165 1
            $this->array[$key] = $value;
166
        }
167 1
    }
168
169
    /**
170
     * @inheritDoc
171
     * @param scalar $key
172
     * @return void
173
     */
174 1
    public function remove($key): void
175
    {
176 1
        unset($this->array[$key]);
177 1
    }
178
179
    /**
180
     * @inheritDoc
181
     * @param callable $predicate
182
     * @return bool
183
     */
184 1
    public function all(callable $predicate): bool
185
    {
186 1
        return $this->count() === $this->filter($predicate)->count();
187
    }
188
189
    /**
190
     * @inheritDoc
191
     * @param callable $predicate
192
     * @return bool
193
     */
194 1
    public function any(callable $predicate): bool
195
    {
196 1
        return $this->filter($predicate)->count() > 0;
197
    }
198
199
    /**
200
     * @inheritDoc
201
     * @param callable|null $predicate
202
     * @return MapInterface
203
     */
204 2
    public function filter(callable $predicate = null): MapInterface
205
    {
206 2
        $map = emptyMap();
207 2
        if ($predicate !== null) {
208
            try {
209 2
                $reflected = new ReflectionFunction($predicate);
210 2
                if (count($reflected->getParameters()) === 1) {
211 2
                    assertValidCallable($predicate, [Pair::class]);
212 2
                    foreach ($this->array as $key => $value) {
213 2
                        if ($predicate(pair($key, $value)) === true) {
214 2
                            $map->put($key, $value);
215
                        }
216
                    }
217
                } else {
218
                    if (count($reflected->getParameters()) === 2) {
219
                        assertValidCallable($predicate, ["scalar", "mixed"]);
220
                    }
221 2
                    foreach ($this->array as $key => $value) {
222
                        if ($predicate($key, $value) === true) {
223
                            $map->put($key, $value);
224
                        }
225
                    }
226
                }
227
            } catch (ReflectionException $ex) {
228 2
                throw new NotApplicableCallableException("Invalid callback.");
229
            }
230
        } else {
231
            $map->array = array_filter($this->array, $predicate);
0 ignored issues
show
Bug introduced by
The property array is declared private in anonymous//src/Map/Functions.php$0 and cannot be accessed from this context.
Loading history...
232
        }
233 2
        return $map;
234
    }
235
236
    /**
237
     * @inheritDoc
238
     * @param scalar $key
239
     * @param callable $default
240
     * @return mixed
241
     */
242
    public function getOrElse($key, callable $default)
243
    {
244
        return $this[$key] ?? $default();
245
    }
246
247
    /**
248
     * @inheritDoc
249
     * @param callable $transform
250
     * @return ListInterface
251
     */
252
    public function map(callable $transform): ListInterface
253
    {
254
        $list = emptyList();
255
        $list->array = array_map($transform, $this->array);
0 ignored issues
show
Bug introduced by
The property array is declared private in anonymous//src/Lists/Functions.php$0 and cannot be accessed from this context.
Loading history...
256
        return $list;
257
    }
258
259
    /**
260
     * @inheritDoc
261
     * @param callable $transform
262
     * @return ListInterface
263
     */
264
    public function mapNotNull(callable $transform): ListInterface
265
    {
266
        $newInstance = emptyList();
267
        $newInstance->setArray(array_values(
268
            array_filter(array_map($transform, $this->array), function ($item) {
269
                return $item !== null;
270
            })
271
        ));
272
        return $newInstance;
273
    }
274
275
    /**
276
     * @inheritDoc
277
     * @param iterable<scalar> $keys
278
     * @param MapInterface
279
     */
280
    public function minus(iterable $keys): MapInterface
281
    {
282
        $newInstance = emptyMap();
283
        foreach ($this->array as $key => $value) {
284
            if (!$this->iterableContainsKey($key, $keys)) {
285
                $newInstance[$key] = $value;
286
            }
287
        }
288
        return $newInstance;
289
    }
290
291
    private function iterableContainsKey(string $key, iterable $keys): bool
292
    {
293
        foreach ($keys as $k) {
294
            if ($k === $key) {
295
                return true;
296
            }
297
        }
298
        return false;
299
    }
300
301
    /**
302
     * @inheritDoc
303
     * @param iterable<Pair<scalar, mixed>> $pairs
304
     * @return MapInterface<scalar, mixed>
305
     */
306
    public function plus(iterable $pairs): MapInterface
307
    {
308
        $map = emptyMap();
309
        $map->array = $this->array;
0 ignored issues
show
Bug introduced by
The property array is declared private in anonymous//src/Map/Functions.php$0 and cannot be accessed from this context.
Loading history...
310
        foreach ($pairs as $pair) {
311
            $map[$pair->getKey()] = $pair->getValue();
312
        }
313
        return $map;
314
    }
315
316
    /**
317
     * @inheritDoc
318
     * @param callable $action f(entry: Pair<scalar, mixed>) -> mixed|void
319
     * @return void
320
     */
321
    public function forEach(callable $action): void
322
    {
323
        foreach ($this->array as $key => $value) {
324
            $action(pair($key, $value));
325
        }
326
    }
327
328
    /**
329
     * @inheritDoc
330
     * @return ListInterface<Pair<scalar, mixed>>
331
     */
332
    public function toList(): ListInterface
333
    {
334
        $list = emptyList();
335
        foreach ($this->array as $key => $value) {
336
            $list->add(pair($key, $value));
337
        }
338
        return $list;
339
    }
340
341
    public function toMap(): MapInterface
342
    {
343
        $newInstance = emptyMap();
344
        $newInstance->array = $this->array;
0 ignored issues
show
Bug introduced by
The property array is declared private in anonymous//src/Map/Functions.php$0 and cannot be accessed from this context.
Loading history...
345
        return $newInstance;
346
    }
347
348
349 1
    public function getIterator(): Iterator
350
    {
351 1
        return new ArrayIterator($this->array);
352
    }
353
}
354