Passed
Push — 1.x ( 658842...03d713 )
by Ulises Jeremias
04:04 queued 01:41
created

Map::clear()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php namespace Mbh\Collection;
2
3
/**
4
 * MBHFramework
5
 *
6
 * @link      https://github.com/MBHFramework/mbh-framework
7
 * @copyright Copyright (c) 2017 Ulises Jeremias Cornejo Fandos
8
 * @license   https://github.com/MBHFramework/mbh-framework/blob/master/LICENSE (MIT License)
9
 */
10
11
use Mbh\Collection\Interfaces\Collection as CollectionInterface;
12
use Mbh\Collection\Interfaces\Hashable as HashableInterface;
13
use Mbh\Collection\Interfaces\Sequenceable as SequenceableInterface;
14
use Traversable;
15
use ArrayAccess;
16
use IteratorAggregate;
17
use OutOfBoundsException;
18
use OutOfRangeException;
19
20
/**
21
 * A Map is a sequential collection of key-value pairs, almost identical to an
22
 * array used in a similar context. Keys can be any type, but must be unique.
23
 *
24
 * @package structures
25
 * @author Ulises Jeremias Cornejo Fandos <[email protected]>
26
 */
27
class Map implements ArrayAccess, CollectionInterface, IteratorAggregate
28
{
29
    use Traits\Collection;
30
    use Traits\Functional;
31
    use Traits\SquaredCapacity;
32
33
    const MIN_CAPACITY = 8.0;
34
35
    /**
36
     * @var FixedArray internal array to store pairs
37
     */
38
    private $pairs;
39
40
    /**
41
     * Creates a new instance.
42
     *
43
     * @param array|Traversable $pairs
44
     */
45
    public function __construct($pairs = [])
46
    {
47
        FixedArray::fromArray([]);
48
49
        $this->pushAll($pairs);
0 ignored issues
show
Bug introduced by
The method pushAll() does not exist on Mbh\Collection\Map. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

49
        $this->/** @scrutinizer ignore-call */ 
50
               pushAll($pairs);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
50
    }
51
52
    /**
53
     * @inheritDoc
54
     */
55
    public function clear()
56
    {
57
        $this->pairs->clear();
58
        $this->capacity = self::MIN_CAPACITY;
59
    }
60
61
    /**
62
     * @inheritDoc
63
     */
64
    public function count(): int
65
    {
66
        return count($this->pairs);
67
    }
68
69
    /**
70
     * Returns the value associated with a key, or an optional default if the
71
     * key is not associated with a value.
72
     *
73
     * @param mixed $key
74
     * @param mixed $default
75
     *
76
     * @return mixed The associated value or fallback default if provided.
77
     *
78
     * @throws OutOfBoundsException if no default was provided and the key is
79
     *                               not associated with a value.
80
     */
81
    public function get($key, $default = null)
82
    {
83
        if (($pair = $this->lookupKey($key))) {
84
            return $pair->value;
85
        }
86
87
        // Check if a default was provided.
88
        if (func_num_args() === 1) {
89
            throw new OutOfBoundsException();
90
        }
91
92
        return $default;
93
    }
94
95
    /**
96
     * Returns whether an association a given key exists.
97
     *
98
     * @param mixed $key
99
     *
100
     * @return bool
101
     */
102
    public function hasKey($key): bool
103
    {
104
        return $this->lookupKey($key) !== null;
105
    }
106
107
    /**
108
     * Returns whether an association for a given value exists.
109
     *
110
     * @param mixed $value
111
     *
112
     * @return bool
113
     */
114
    public function hasValue($value): bool
115
    {
116
        return $this->lookupValue($value) !== null;
117
    }
118
119
    /**
120
     * Returns a set of all the keys in the map.
121
     *
122
     * @return Set
123
     */
124
    public function keys(): Set
0 ignored issues
show
Bug introduced by
The type Mbh\Collection\Set was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
125
    {
126
        return new static($this->pairs->map(function ($pair) {
0 ignored issues
show
Bug Best Practice introduced by
The expression return new static($this-...on(...) { /* ... */ })) returns the type Mbh\Collection\Map which is incompatible with the type-hinted return Mbh\Collection\Set.
Loading history...
127
            return $pair->key;
128
        }));
129
    }
130
131
    /**
132
     * Determines whether two keys are equal.
133
     *
134
     * @param mixed $a
135
     * @param mixed $b
136
     *
137
     * @return bool
138
     */
139
    private function keysAreEqual($a, $b): bool
140
    {
141
        if (is_object($a) && $a instanceof HashableInterface) {
142
            return get_class($a) === get_class($b) && $a->equals($b);
143
        }
144
145
        return $a === $b;
146
    }
147
148
    /**
149
     * Attempts to look up a key in the table.
150
     *
151
     * @param $key
152
     *
153
     * @return Pair|null
154
     */
155
    private function lookupKey($key)
156
    {
157
        foreach ($this->pairs as $pair) {
158
            if ($this->keysAreEqual($pair->key, $key)) {
159
                return $pair;
160
            }
161
        }
162
    }
163
164
    /**
165
     * Attempts to look up a key in the table.
166
     *
167
     * @param $value
168
     *
169
     * @return Pair|null
170
     */
171
    private function lookupValue($value)
172
    {
173
        foreach ($this->pairs as $pair) {
174
            if ($pair->value === $value) {
175
                return $pair;
176
            }
177
        }
178
    }
179
180
    /**
181
     * Returns a sequence of pairs representing all associations.
182
     *
183
     * @return SequenceableInterface
184
     */
185
    public function pairs(): SequenceableInterface
186
    {
187
        return $this->pairs->map(function ($pair) {
188
            return $pair->copy();
189
        });
190
    }
191
192
    /**
193
     * Associates a key with a value, replacing a previous association if there
194
     * was one.
195
     *
196
     * @param mixed $key
197
     * @param mixed $value
198
     */
199
    public function put($key, $value)
200
    {
201
        $pair = $this->lookupKey($key);
202
        if ($pair) {
203
            $pair->value = $value;
204
        } else {
205
            $this->checkCapacity();
206
            $this->pairs[] = new Pair($key, $value);
207
        }
208
    }
209
210
    /**
211
     * Creates associations for all keys and corresponding values of either an
212
     * array or iterable object.
213
     *
214
     * @param Traversable|array $values
215
     */
216
    public function putAll($values)
217
    {
218
        foreach ($values as $key => $value) {
219
            $this->put($key, $value);
220
        }
221
    }
222
223
    /**
224
     * Returns a sequence of all the associated values in the Map.
225
     *
226
     * @return SequenceableInterface
227
     */
228
    public function values(): SequenceableInterface
229
    {
230
        return $this->pairs->map(function ($pair) {
231
            return $pair->value;
232
        });
233
    }
234
235
    /**
236
     * @inheritDoc
237
     */
238
    public function getIterator()
239
    {
240
        foreach ($this->pairs as $pair) {
241
            yield $pair->key => $pair->value;
242
        }
243
    }
244
245
    /**
246
     * Returns a representation to be used for var_dump and print_r.
247
     */
248
    public function __debugInfo()
249
    {
250
        return $this->pairs()->toArray();
251
    }
252
253
    /**
254
     * @inheritdoc
255
     */
256
    public function offsetSet($offset, $value)
257
    {
258
        $this->put($offset, $value);
259
    }
260
261
    /**
262
     * @inheritdoc
263
     *
264
     * @throws OutOfBoundsException
265
     */
266
    public function &offsetGet($offset)
267
    {
268
        $pair = $this->lookupKey($offset);
269
        if ($pair) {
270
            return $pair->value;
271
        }
272
        throw new OutOfBoundsException();
273
    }
274
275
    /**
276
     * @inheritdoc
277
     */
278
    public function offsetUnset($offset)
279
    {
280
        $this->remove($offset, null);
0 ignored issues
show
Bug introduced by
The method remove() does not exist on Mbh\Collection\Map. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

280
        $this->/** @scrutinizer ignore-call */ 
281
               remove($offset, null);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
281
    }
282
283
    /**
284
     * @inheritdoc
285
     */
286
    public function offsetExists($offset)
287
    {
288
        return $this->get($offset, null) !== null;
289
    }
290
}
291