1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
// Copyright (c) italolelis. All rights reserved. See License.txt in the project root for license information. |
4
|
|
|
namespace Collections; |
5
|
|
|
|
6
|
|
|
use Collections\Exception\KeyException; |
7
|
|
|
use Collections\Iterator\MapIterator; |
8
|
|
|
use Collections\Traits\GuardTrait; |
9
|
|
|
use Collections\Traits\StrictKeyedIterableTrait; |
10
|
|
|
|
11
|
|
|
/** |
12
|
|
|
* Represents a collection of keys and values. |
13
|
|
|
*/ |
14
|
|
|
class Dictionary extends AbstractConstCollectionArray implements MapInterface, \ArrayAccess |
15
|
|
|
{ |
16
|
|
|
use GuardTrait, |
17
|
|
|
StrictKeyedIterableTrait; |
18
|
|
|
|
19
|
|
|
public function at($k) |
20
|
|
|
{ |
21
|
|
|
return $this[$k]; |
22
|
|
|
} |
23
|
|
|
|
24
|
|
|
public function set($key, $value) |
25
|
|
|
{ |
26
|
22 |
|
$this->container[$key] = $value; |
27
|
|
|
|
28
|
22 |
|
return $this; |
29
|
|
|
} |
30
|
22 |
|
|
31
|
|
|
/** |
32
|
|
|
* {@inheritdoc} |
33
|
|
|
*/ |
34
|
|
View Code Duplication |
public function get($index) |
|
|
|
|
35
|
|
|
{ |
36
|
8 |
|
if ($this->containsKey($index) === false) { |
37
|
|
|
throw new \OutOfBoundsException('No element at position ' . $index); |
38
|
8 |
|
} |
39
|
1 |
|
|
40
|
|
|
return $this->container[$index]; |
41
|
|
|
} |
42
|
7 |
|
|
43
|
|
|
/** |
44
|
|
|
* {@inheritdoc} |
45
|
|
|
*/ |
46
|
|
|
public function tryGet($index, $default = null) |
47
|
|
|
{ |
48
|
12 |
|
if ($this->containsKey($index) === false) { |
49
|
|
|
return $default; |
50
|
12 |
|
} |
51
|
1 |
|
|
52
|
|
|
return $this->get($index); |
53
|
12 |
|
} |
54
|
|
|
|
55
|
12 |
|
/** |
56
|
|
|
* {@inheritdoc} |
57
|
|
|
*/ |
58
|
|
|
public function add($key, $value) |
59
|
|
|
{ |
60
|
|
|
if ($this->containsKey($key)) { |
61
|
4 |
|
throw new KeyException('The key ' . $key . ' already exists!'); |
62
|
|
|
} |
63
|
4 |
|
|
64
|
1 |
|
$this->set($key, $value); |
65
|
|
|
|
66
|
|
|
return $this; |
67
|
3 |
|
} |
68
|
3 |
|
|
69
|
1 |
|
/** |
70
|
1 |
|
* {@inheritdoc} |
71
|
3 |
|
*/ |
72
|
3 |
View Code Duplication |
public function addAll($items) |
|
|
|
|
73
|
3 |
|
{ |
74
|
|
|
$this->validateTraversable($items); |
75
|
|
|
|
76
|
|
|
foreach ($items as $key => $value) { |
77
|
|
|
if (is_array($value)) { |
78
|
17 |
|
$value = new static($value); |
79
|
|
|
} |
80
|
17 |
|
$this->add($key, $value); |
81
|
|
|
} |
82
|
|
|
} |
83
|
|
|
|
84
|
|
|
/** |
85
|
|
|
* {@inheritdoc} |
86
|
|
|
*/ |
87
|
|
View Code Duplication |
public function setAll($items) |
|
|
|
|
88
|
|
|
{ |
89
|
|
|
$this->validateTraversable($items); |
90
|
|
|
|
91
|
|
|
foreach ($items as $key => $item) { |
92
|
|
|
if (is_array($item)) { |
93
|
|
|
$item = new static($item); |
94
|
1 |
|
} |
95
|
|
|
$this->set($key, $item); |
96
|
1 |
|
} |
97
|
1 |
|
|
98
|
|
|
return $this; |
99
|
|
|
} |
100
|
|
|
|
101
|
|
|
/** |
102
|
|
|
* {@inheritdoc} |
103
|
|
|
*/ |
104
|
|
|
public function containsKey($key) |
105
|
2 |
|
{ |
106
|
|
|
return array_key_exists($key, $this->container); |
107
|
2 |
|
} |
108
|
1 |
|
|
109
|
|
|
/** |
110
|
1 |
|
* {@inheritdoc} |
111
|
|
|
*/ |
112
|
|
|
public function contains($element) |
113
|
|
|
{ |
114
|
|
|
return in_array($element, $this->container, true); |
115
|
|
|
} |
116
|
1 |
|
|
117
|
|
|
/** |
118
|
1 |
|
* {@inheritdoc} |
119
|
|
|
*/ |
120
|
|
|
public function remove($element) |
121
|
|
|
{ |
122
|
|
|
$key = array_search($element, $this->container); |
123
|
|
|
|
124
|
5 |
|
if (false === $key) { |
125
|
|
|
throw new \OutOfBoundsException('No element found in the collection '); |
126
|
5 |
|
} |
127
|
|
|
|
128
|
|
|
$this->removeKey($key); |
129
|
|
|
|
130
|
|
|
return $this; |
131
|
|
|
} |
132
|
10 |
|
|
133
|
|
|
/** |
134
|
10 |
|
* {@inheritdoc} |
135
|
|
|
*/ |
136
|
|
View Code Duplication |
public function removeKey($key) |
|
|
|
|
137
|
10 |
|
{ |
138
|
|
|
if ($this->containsKey($key) === false) { |
139
|
10 |
|
throw new \OutOfBoundsException('No element at position ' . $key); |
140
|
|
|
} |
141
|
|
|
|
142
|
|
|
unset($this->container[$key]); |
143
|
|
|
|
144
|
1 |
|
return $this; |
145
|
|
|
} |
146
|
1 |
|
|
147
|
1 |
|
/** |
148
|
|
|
* {@inheritdoc} |
149
|
|
|
*/ |
150
|
|
|
public function offsetExists($offset) |
151
|
|
|
{ |
152
|
|
|
return isset($this->container[$offset]) || array_key_exists($offset, $this->container); |
153
|
10 |
|
} |
154
|
|
|
|
155
|
10 |
|
/** |
156
|
|
|
* {@inheritdoc} |
157
|
|
|
*/ |
158
|
|
|
public function offsetGet($offset) |
159
|
|
|
{ |
160
|
|
|
return $this->get($offset); |
161
|
|
|
} |
162
|
|
|
|
163
|
|
|
/** |
164
|
|
|
* {@inheritdoc} |
165
|
|
|
*/ |
166
|
|
|
public function offsetSet($offset, $value) |
167
|
|
|
{ |
168
|
|
|
if (is_null($offset)) { |
169
|
|
|
$this->add($offset, $value); |
170
|
|
|
} else { |
171
|
|
|
$this->set($offset, $value); |
172
|
|
|
} |
173
|
|
|
} |
174
|
|
|
|
175
|
|
|
/** |
176
|
|
|
* {@inheritdoc} |
177
|
|
|
*/ |
178
|
|
|
public function offsetUnset($offset) |
179
|
|
|
{ |
180
|
|
|
$this->removeKey($offset); |
181
|
|
|
} |
182
|
|
|
|
183
|
|
|
/** |
184
|
|
|
* Gets the collection's iterator |
185
|
|
|
* @return MapIterator |
186
|
|
|
*/ |
187
|
|
|
public function getIterator() |
188
|
|
|
{ |
189
|
|
|
return new MapIterator($this->container); |
190
|
|
|
} |
191
|
|
|
|
192
|
|
|
/** |
193
|
|
|
* {@inheritDoc} |
194
|
|
|
* @return $this |
195
|
|
|
*/ |
196
|
|
|
public function concat($iterable) |
197
|
|
|
{ |
198
|
|
|
$this->validateTraversable($iterable); |
199
|
|
|
|
200
|
|
|
$this->setAll($this->concatRecurse($this, $iterable)); |
201
|
|
|
|
202
|
|
|
return $this; |
203
|
|
|
} |
204
|
|
|
} |
205
|
|
|
|
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.