Completed
Push — master ( 6792a2...fd231f )
by Thomas
02:04
created

Map   A

Complexity

Total Complexity 34

Size/Duplication

Total Lines 253
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 34
lcom 1
cbo 4
dl 0
loc 253
ccs 86
cts 86
cp 1
rs 9.2
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 18
	public function __construct($collection = []) {
21 18
		$this->setAll($collection);
22 18
	}
23
	
24
	/**
25
	 * @param string|Text $key
26
	 * @return string
27
	 */
28 18
	private function extractKey($key) {
29 18
		if ($key instanceof Text) {
30 1
			return $key->toString();
31
		}
32
		
33 17
		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 17
	public function set($key, $element) {
44 17
		$key = $this->extractKey($key);
45 17
		$this->collection[$key] = $element;
46
		
47 17
		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 5
	public function get($key, $default = null) {
58 5
		$key = $this->extractKey($key);
59 5
		if (isset($this->collection[$key])) {
60 5
			return $this->collection[$key];
61
		} else {
62 1
			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 2
	public function getKey($value) {
73 2
		foreach ($this->collection as $k => $v) {
74 2
			if ($v === $value) {
75 2
				return $k;
76
			}
77 2
		}
78
		
79 1
		return null;
80
	}
81
82
	/**
83
	 * Sets many elements on that map
84
	 * 
85
	 * @param array|Iterator $collection
86
	 * @return Map $this
87
	 */
88 18
	public function setAll($collection) {
89 18
		foreach ($collection as $key => $element) {
90 10
			$this->set($key, $element);
91 18
		}
92
		
93 18
		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 2
	public function remove($key) {
104 2
		$key = $this->extractKey($key);
105 2
		if (isset($this->collection[$key])) {
106 2
			$element = $this->collection[$key];
107 2
			unset($this->collection[$key]);
108
			
109 2
			return $element;
110
		}
111 1
	}
112
	
113
	/**
114
	 * Returns all keys as Set
115
	 * 
116
	 * @return Set the map's keys
117
	 */
118 1
	public function keys() {
119 1
		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 1
	public function values() {
128 1
		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 3
	public function has($key) {
138 3
		$key = $this->extractKey($key);
139 3
		return isset($this->collection[$key]);
140
	}
141
	
142
	/**
143
	 * Sorts the map
144
	 *
145
	 * @param Comparator|callable $cmp
146
	 * @return $this
147
	 */
148 1
	public function sort($cmp = null) {
149 1
		$this->doSort($this->collection, $cmp, 'uasort', 'asort');
150
	
151 1
		return $this;
152
	}
153
	
154
	/**
155
	 * Sorts the map by keys
156
	 *
157
	 * @param Comparator|callable $cmp
158
	 * @return $this
159
	 */
160 1
	public function sortKeys($cmp = null) {
161 1
		$this->doSort($this->collection, $cmp, 'uksort', 'ksort');
162
	
163 1
		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 1
	public function each(callable $callback) {
172 1
		foreach ($this->collection as $key => $value) {
173 1
			$callback($key, $value);
174 1
		}
175 1
	}
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 1
	public function findKey() {
191 1
		if (func_num_args() == 1) {
192 1
			$callback = func_get_arg(0);
193 1
		} else {
194 1
			$query = func_get_arg(0);
195 1
			$callback = func_get_arg(1);
196
		}
197
		
198 1
		$index = func_num_args() == 1 ? $this->find($callback) : $this->find($query, $callback);
199 1
		if ($index !== null) {
200 1
			$index = $this->getKey($index);
201 1
		}
202
	
203 1
		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 1
	public function findLastKey() {
220 1
		if (func_num_args() == 1) {
221 1
			$callback = func_get_arg(0);
222 1
		} else {
223 1
			$query = func_get_arg(0);
224 1
			$callback = func_get_arg(1);
225
		}
226
227 1
		$index = func_num_args() == 1 ? $this->findLast($callback) : $this->findLast($query, $callback);
228 1
		if ($index !== null) {
229 1
			$index = $this->getKey($index);
230 1
		}
231
	
232 1
		return $index;
233
	}
234
235
	/**
236
	 * @internal
237
	 */
238 1
	public function offsetSet($offset, $value) {
239 1
		if (!is_null($offset)) {
240 1
			$this->collection[$offset] = $value;
241 1
		}
242 1
	}
243
	
244
	/**
245
	 * @internal
246
	 */
247 1
	public function offsetExists($offset) {
248 1
		return isset($this->collection[$offset]);
249
	}
250
	
251
	/**
252
	 * @internal
253
	 */
254 1
	public function offsetUnset($offset) {
255 1
		unset($this->collection[$offset]);
256 1
	}
257
	
258
	/**
259
	 * @internal
260
	 */
261 1
	public function offsetGet($offset) {
262 1
		return isset($this->collection[$offset]) ? $this->collection[$offset] : null;
263
	}	
264
	
265
}
266