Map   A
last analyzed

Complexity

Total Complexity 34

Size/Duplication

Total Lines 253
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 0
Metric Value
wmc 34
lcom 1
cbo 4
dl 0
loc 253
rs 9.68
c 0
b 0
f 0

19 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A extractKey() 0 7 2
A set() 0 6 1
A get() 0 8 2
A getKey() 0 9 3
A setAll() 0 7 2
A remove() 0 9 2
A keys() 0 3 1
A values() 0 3 1
A has() 0 4 1
A sort() 0 5 1
A sortKeys() 0 5 1
A each() 0 5 2
A findKey() 0 15 4
A findLastKey() 0 15 4
A offsetSet() 0 5 2
A offsetExists() 0 3 1
A offsetUnset() 0 3 1
A offsetGet() 0 3 2
1
<?php
2
namespace phootwork\collection;
3
4
use \Iterator;
5
use phootwork\lang\Comparator;
6
use phootwork\lang\Text;
7
8
/**
9
 * Represents a Map
10
 * 
11
 * @author Thomas Gossmann
12
 */
13
class Map extends AbstractCollection implements \ArrayAccess {
14
	
15
	/**
16
	 * Creates a new Map
17
	 * 
18
	 * @param array|Iterator $collection
19
	 */
20
	public function __construct($collection = []) {
21
		$this->setAll($collection);
22
	}
23
	
24
	/**
25
	 * @param string|Text $key
26
	 * @return string
27
	 */
28
	private function extractKey($key) {
29
		if ($key instanceof Text) {
30
			return $key->toString();
31
		}
32
		
33
		return $key;
34
	}
35
	
36
	/**
37
	 * Sets an element with the given key on that map
38
	 * 
39
	 * @param string key
40
	 * @param mixed $element
41
	 * @return Map $this
42
	 */
43
	public function set($key, $element) {
44
		$key = $this->extractKey($key);
45
		$this->collection[$key] = $element;
46
		
47
		return $this;
48
	}
49
	
50
	/**
51
	 * Returns the element for the given key or your value, if the key doesn't exist.
52
	 * 
53
	 * @param string $key
54
	 * @param mixed $default the return value, if the key doesn't exist
55
	 * @return mixed
56
	 */
57
	public function get($key, $default = null) {
58
		$key = $this->extractKey($key);
59
		if (isset($this->collection[$key])) {
60
			return $this->collection[$key];
61
		} else {
62
			return $default;
63
		}
64
	}
65
	
66
	/**
67
	 * Returns the key for the given value
68
	 * 
69
	 * @param mixed $value the value
70
	 * @return mixed
71
	 */
72
	public function getKey($value) {
73
		foreach ($this->collection as $k => $v) {
74
			if ($v === $value) {
75
				return $k;
76
			}
77
		}
78
		
79
		return null;
80
	}
81
82
	/**
83
	 * Sets many elements on that map
84
	 * 
85
	 * @param array|Iterator $collection
86
	 * @return Map $this
87
	 */
88
	public function setAll($collection) {
89
		foreach ($collection as $key => $element) {
90
			$this->set($key, $element);
91
		}
92
		
93
		return $this;
94
	}
95
	
96
	/**
97
	 * Removes and returns an element from the map by the given key. Returns null if the key
98
	 * does not exist.
99
	 * 
100
	 * @param string $key
101
	 * @return mixed the element at the given key
102
	 */
103
	public function remove($key) {
104
		$key = $this->extractKey($key);
105
		if (isset($this->collection[$key])) {
106
			$element = $this->collection[$key];
107
			unset($this->collection[$key]);
108
			
109
			return $element;
110
		}
111
	}
112
	
113
	/**
114
	 * Returns all keys as Set
115
	 * 
116
	 * @return Set the map's keys
117
	 */
118
	public function keys() {
119
		return new Set(array_keys($this->collection));
120
	}
121
	
122
	/**
123
	 * Returns all values as ArrayList
124
	 * 
125
	 * @return ArrayList the map's values
126
	 */
127
	public function values() {
128
		return new ArrayList(array_values($this->collection));
129
	}
130
131
	/**
132
	 * Returns whether the key exist.
133
	 * 
134
	 * @param string $key
135
	 * @return boolean
136
	 */
137
	public function has($key) {
138
		$key = $this->extractKey($key);
139
		return isset($this->collection[$key]);
140
	}
141
	
142
	/**
143
	 * Sorts the map
144
	 *
145
	 * @param Comparator|callable $cmp
146
	 * @return $this
147
	 */
148
	public function sort($cmp = null) {
149
		$this->doSort($this->collection, $cmp, 'uasort', 'asort');
150
	
151
		return $this;
152
	}
153
	
154
	/**
155
	 * Sorts the map by keys
156
	 *
157
	 * @param Comparator|callable $cmp
158
	 * @return $this
159
	 */
160
	public function sortKeys($cmp = null) {
161
		$this->doSort($this->collection, $cmp, 'uksort', 'ksort');
162
	
163
		return $this;
164
	}
165
	
166
	/**
167
	 * Iterates the map and calls the callback function with the current key and value as parameters
168
	 *
169
	 * @param callable $callback
170
	 */
171
	public function each(callable $callback) {
172
		foreach ($this->collection as $key => $value) {
173
			$callback($key, $value);
174
		}
175
	}
176
	
177
	/**
178
	 * Searches the collection with a given callback and returns the key for the first element if found.
179
	 *
180
	 * The callback function takes one or two parameters:
181
	 *
182
	 *     function ($element [, $query]) {}
183
	 *
184
	 * The callback must return a boolean
185
	 *
186
	 * @param mixed $query OPTIONAL the provided query
187
	 * @param callable $callback the callback function
188
	 * @return mixed|null the key or null if it hasn't been found
189
	 */
190
	public function findKey() {
191
		if (func_num_args() == 1) {
192
			$callback = func_get_arg(0);
193
		} else {
194
			$query = func_get_arg(0);
195
			$callback = func_get_arg(1);
196
		}
197
		
198
		$index = func_num_args() == 1 ? $this->find($callback) : $this->find($query, $callback);
199
		if ($index !== null) {
200
			$index = $this->getKey($index);
201
		}
202
	
203
		return $index;
204
	}
205
	
206
	/**
207
	 * Searches the collection with a given callback and returns the key for the last element if found.
208
	 *
209
	 * The callback function takes one or two parameters:
210
	 *
211
	 *     function ($element [, $query]) {}
212
	 *
213
	 * The callback must return a boolean
214
	 *
215
	 * @param mixed $query OPTIONAL the provided query
216
	 * @param callable $callback the callback function
217
	 * @return mixed|null the key or null if it hasn't been found
218
	 */
219
	public function findLastKey() {
220
		if (func_num_args() == 1) {
221
			$callback = func_get_arg(0);
222
		} else {
223
			$query = func_get_arg(0);
224
			$callback = func_get_arg(1);
225
		}
226
227
		$index = func_num_args() == 1 ? $this->findLast($callback) : $this->findLast($query, $callback);
228
		if ($index !== null) {
229
			$index = $this->getKey($index);
230
		}
231
	
232
		return $index;
233
	}
234
235
	/**
236
	 * @internal
237
	 */
238
	public function offsetSet($offset, $value) {
239
		if (!is_null($offset)) {
240
			$this->collection[$offset] = $value;
241
		}
242
	}
243
	
244
	/**
245
	 * @internal
246
	 */
247
	public function offsetExists($offset) {
248
		return isset($this->collection[$offset]);
249
	}
250
	
251
	/**
252
	 * @internal
253
	 */
254
	public function offsetUnset($offset) {
255
		unset($this->collection[$offset]);
256
	}
257
	
258
	/**
259
	 * @internal
260
	 */
261
	public function offsetGet($offset) {
262
		return isset($this->collection[$offset]) ? $this->collection[$offset] : null;
263
	}	
264
	
265
}
266