Completed
Push — master ( cc51b8...3f6140 )
by Nate
02:16
created

HashMap::filter()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 13
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 13
ccs 6
cts 6
cp 1
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 6
nc 3
nop 1
crap 3
1
<?php
2
/*
3
 * Copyright (c) Nate Brunette.
4
 * Distributed under the MIT License (http://opensource.org/licenses/MIT)
5
 */
6
7
namespace Tebru\Collection;
8
9
use OutOfRangeException;
10
11
/**
12
 * Class HashMap
13
 *
14
 * [@see MapInterface] implementation
15
 *
16
 * @author Nate Brunette <[email protected]>
17
 */
18
class HashMap extends AbstractMap
19
{
20
    /**
21
     * The mapping keys
22
     *
23
     * @var array
24
     */
25
    protected $keys = [];
26
27
    /**
28
     * The mapping values
29
     *
30
     * @var array
31
     */
32
    protected $values = [];
33
34
    /**
35
     * Removes all mappings from map
36
     *
37
     * @return void
38
     */
39 1
    public function clear()
40
    {
41 1
        $this->keys = [];
42 1
        $this->values = [];
43 1
    }
44
45
    /**
46
     * Returns true if the key exists in the map
47
     *
48
     * By default this method will use strict comparison checking, passing false
49
     * in will use a double equals (==) instead.
50
     *
51
     * @param mixed $key
52
     * @param bool $strict
53
     * @return bool
54
     */
55 26
    public function containsKey($key, bool $strict = true): bool
56
    {
57 26
        return in_array($key, $this->keys, $strict);
58
    }
59
60
    /**
61
     * Returns true if the value exists in the map
62
     *
63
     * By default this method will use strict comparison checking, passing false
64
     * in will use a double equals (==) instead.
65
     *
66
     * @param mixed $value
67
     * @param bool $strict
68
     * @return bool
69
     */
70 3
    public function containsValue($value, bool $strict = true): bool
71
    {
72 3
        return in_array($value, $this->values, $strict);
73
    }
74
75
    /**
76
     * Return a set representation of map
77
     *
78
     * If a set is passed in, that set will be populated, otherwise
79
     * a default set will be used.
80
     *
81
     * @param SetInterface $set
82
     * @return SetInterface
83
     */
84 5
    public function entrySet(SetInterface $set = null): SetInterface
85
    {
86 5
        $set = $set ?? new HashSet();
87 5
        foreach ($this->keys as $index => $key) {
88 5
            $set->add(new MapEntry($key, $this->values[$index]));
89
        }
90
91 5
        return $set;
92
    }
93
94
    /**
95
     * Get the value at the specified key
96
     *
97
     * By default this method will use strict comparison checking, passing false
98
     * in will use a double equals (==) instead.
99
     *
100
     * @param mixed $key
101
     * @param bool $strict
102
     * @return mixed
103
     * @throws \OutOfRangeException if the key doesn't exist
104
     */
105 7
    public function get($key, bool $strict = true)
106
    {
107 7
        if (!$this->containsKey($key, $strict)) {
108 1
            throw new OutOfRangeException(sprintf('Tried to access array at key "%s"', $key));
109
        }
110
111 6
        $index = array_search($key, $this->keys, $strict);
112
113 6
        return $this->values[$index];
114
    }
115
116
    /**
117
     * Returns true if the map is empty
118
     *
119
     * @return bool
120
     */
121 2
    public function isEmpty(): bool
122
    {
123 2
        return 0 === $this->count();
124
    }
125
126
    /**
127
     * Returns a set of they keys in the map
128
     *
129
     * If a set is passed in, that set will be populated, otherwise
130
     * a default set will be used.
131
     *
132
     * @param SetInterface $set
133
     * @return SetInterface
134
     */
135 2
    public function keySet(SetInterface $set = null): SetInterface
136
    {
137 2
        if (null === $set) {
138 1
            return new HashSet(new ArrayList($this->keys));
139
        }
140
141 1
        $set->addAll(new ArrayList($this->keys));
142
143 1
        return $set;
144
    }
145
146
    /**
147
     * Returns the previous value or null if there was no value
148
     *
149
     * By default this method will use strict comparison checking, passing false
150
     * in will use a double equals (==) instead.
151
     *
152
     * @param mixed $key
153
     * @param mixed $value
154
     * @param bool $strict
155
     * @return mixed
156
     */
157 26
    public function put($key, $value, bool $strict = true)
158
    {
159 26
        $oldValue = null;
160 26
        if ($this->containsKey($key, $strict)) {
161 2
            $oldValue = $this->get($key, $strict);
162 2
            $this->remove($key, $strict);
163
        }
164
165 26
        $this->keys[] = $key;
166 26
        $this->values[] = $value;
167
168 26
        return $oldValue;
169
    }
170
171
    /**
172
     * Remove the mapping for the key and returns the previous value
173
     * or null
174
     *
175
     * By default this method will use strict comparison checking, passing false
176
     * in will use a double equals (==) instead.
177
     *
178
     * @param mixed $key
179
     * @param bool $strict
180
     * @return mixed
181
     */
182 5
    public function remove($key, bool $strict = true)
183
    {
184 5
        if (!$this->containsKey($key, $strict)) {
185 1
            return false;
186
        }
187
188 4
        $oldValue = $this->get($key, $strict);
189 4
        $index = array_search($key, $this->keys, $strict);
190
191 4
        array_splice($this->keys, $index, 1);
192 4
        array_splice($this->values, $index, 1);
193
194 4
        return $oldValue;
195
    }
196
197
    /**
198
     * Returns the number of mappings in the map
199
     *
200
     * @return int
201
     */
202 7
    public function count(): int
203
    {
204 7
        return count($this->keys);
205
    }
206
207
    /**
208
     * Returns the keys as a collection
209
     *
210
     * @param CollectionInterface $collection
211
     * @return CollectionInterface
212
     */
213 9 View Code Duplication
    public function keys(CollectionInterface $collection = null): CollectionInterface
1 ignored issue
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
214
    {
215 9
        if (null === $collection) {
216 8
            return new ArrayList($this->keys);
217
        }
218
219 1
        $collection->addAll(new ArrayList($this->keys));
220
221 1
        return $collection;
222
    }
223
224
    /**
225
     * Returns the values as a collection
226
     *
227
     * @param CollectionInterface $collection
228
     * @return CollectionInterface
229
     */
230 2 View Code Duplication
    public function values(CollectionInterface $collection = null): CollectionInterface
1 ignored issue
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
231
    {
232 2
        if (null === $collection) {
233 1
            return new ArrayList($this->values);
234
        }
235
236 1
        $collection->addAll(new ArrayList($this->values));
237
238 1
        return $collection;
239
    }
240
241
    /**
242
     * Filter the collection using closure
243
     *
244
     * The closure will get passed a [@see MapEntry].  Returning true from the
245
     * closure will include that entry in the new map.
246
     *
247
     * @param callable $filter
248
     * @return MapInterface
249
     */
250 1
    public function filter(callable $filter): MapInterface
251
    {
252 1
        $map = new HashMap();
253
254
        /** @var MapEntry $mapEntry */
255 1
        foreach ($this->entrySet() as $mapEntry) {
256 1
            if (false !== $filter($mapEntry)) {
257 1
                $map->put($mapEntry->key, $mapEntry->value);
258
            }
259
        }
260
261 1
        return $map;
262
    }
263
264
265
}
266