1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* DataStructures for PHP |
4
|
|
|
* |
5
|
|
|
* @link https://github.com/SiroDiaz/DataStructures |
6
|
|
|
* @copyright Copyright (c) 2017 Siro Díaz Palazón |
7
|
|
|
* @license https://github.com/SiroDiaz/DataStructures/blob/master/README.md (MIT License) |
8
|
|
|
*/ |
9
|
|
|
namespace DataStructures\Lists; |
10
|
|
|
|
11
|
|
|
use DataStructures\Lists\Interfaces\ListInterface; |
12
|
|
|
use OutOfBoundsException; |
13
|
|
|
|
14
|
|
|
/** |
15
|
|
|
* ArrayList |
16
|
|
|
* |
17
|
|
|
* This class is an implementation of a list based in native arrays. |
18
|
|
|
* The access time is, in general, O(1) since all in PHP is a hash table. |
19
|
|
|
* |
20
|
|
|
* @author Siro Diaz Palazon <[email protected]> |
21
|
|
|
*/ |
22
|
|
|
class ArrayList implements ListInterface { |
23
|
|
|
private $data; |
24
|
|
|
private $current; |
25
|
|
|
private $position; |
26
|
|
|
private $size; |
27
|
|
|
|
28
|
|
|
public function __construct() { |
29
|
|
|
$this->data = []; |
30
|
|
|
$this->size = 0; |
31
|
|
|
$this->position = 0; |
32
|
|
|
} |
33
|
|
|
|
34
|
|
|
/** |
35
|
|
|
* Add a new node in the specified index. |
36
|
|
|
* |
37
|
|
|
* @param integer $index the position. |
38
|
|
|
* @param mixed $data the data to be stored. |
39
|
|
|
*/ |
40
|
|
|
public function insert($index, $data) { |
41
|
|
|
array_splice($this->data, $index, 0, $data); |
42
|
|
|
$this->size++; |
43
|
|
|
} |
44
|
|
|
|
45
|
|
|
/** |
46
|
|
|
* Removes all the array items. |
47
|
|
|
*/ |
48
|
|
|
public function clear() { |
49
|
|
|
$this->data = []; |
50
|
|
|
$this->size = 0; |
51
|
|
|
} |
52
|
|
|
|
53
|
|
|
/** |
54
|
|
|
* Returns the array in the especified index. |
55
|
|
|
* |
56
|
|
|
* @param integer $index Index that must be greater than 0 |
57
|
|
|
* and lower than the list size. |
58
|
|
|
* @return mixed The data stored in the given index |
59
|
|
|
* @throws OutOfBoundsException if index is out bounds. |
60
|
|
|
*/ |
61
|
|
|
public function get($index) { |
62
|
|
|
if($index < 0 || $index > $this->size - 1) { |
63
|
|
|
throw new OutOfBoundsException(); |
64
|
|
|
} |
65
|
|
|
|
66
|
|
|
return $this->data[$index]; |
67
|
|
|
} |
68
|
|
|
|
69
|
|
|
/** |
70
|
|
|
* Returns the last node with O(1). |
71
|
|
|
* |
72
|
|
|
* @return mixed null if the array is empty. |
73
|
|
|
*/ |
74
|
|
|
public function getLast() { |
75
|
|
|
if(!$this->empty()) { |
76
|
|
|
return $this->data[$this->size - 1]; |
77
|
|
|
} |
78
|
|
|
|
79
|
|
|
return null; |
80
|
|
|
} |
81
|
|
|
|
82
|
|
|
public function getAll() { |
83
|
|
|
foreach($this->data as $data) { |
84
|
|
|
yield $data; |
85
|
|
|
} |
86
|
|
|
} |
87
|
|
|
|
88
|
|
|
public function empty() : bool { |
89
|
|
|
return $this->size === 0; |
90
|
|
|
} |
91
|
|
|
|
92
|
|
|
/** |
93
|
|
|
* Removes and returns the last item in the array. |
94
|
|
|
* |
95
|
|
|
* @return mixed data in node. |
96
|
|
|
*/ |
97
|
|
|
public function pop() { |
98
|
|
|
return $this->delete(($this->size === 0) ? 0 : $this->size - 1); |
99
|
|
|
} |
100
|
|
|
|
101
|
|
|
/** |
102
|
|
|
* Adds at the end of the list new node containing |
103
|
|
|
* the data to be stored. |
104
|
|
|
* |
105
|
|
|
* @param mixed $data The data |
106
|
|
|
*/ |
107
|
|
|
public function push($data) { |
108
|
|
|
$this->data[] = $data; |
109
|
|
|
$this->size++; |
110
|
|
|
} |
111
|
|
|
|
112
|
|
|
/** |
113
|
|
|
* Adds at the beginning a node in the list. |
114
|
|
|
* |
115
|
|
|
* @param mixed $data |
116
|
|
|
* @return mixed the data stored. |
117
|
|
|
*/ |
118
|
|
|
public function unshift($data) { |
119
|
|
|
$this->insert(0, $data); |
120
|
|
|
} |
121
|
|
|
|
122
|
|
|
/** |
123
|
|
|
* Delete a node in the given position and returns it back. |
124
|
|
|
* |
125
|
|
|
* @param integer $index the position. |
126
|
|
|
* @throws OutOfBoundsException if index is negative |
127
|
|
|
* or is greater than the size of the list. |
128
|
|
|
*/ |
129
|
|
|
public function delete($index) { |
130
|
|
|
if($this->size === 0 || $index < 0 || $index > $this->size - 1) { |
131
|
|
|
throw new OutOfBoundsException(); |
132
|
|
|
} |
133
|
|
|
|
134
|
|
|
$data = $this->data[$index]; |
135
|
|
|
array_splice($this->data, $index, 1); |
136
|
|
|
$this->size--; |
137
|
|
|
|
138
|
|
|
return $data; |
139
|
|
|
} |
140
|
|
|
|
141
|
|
|
/** |
142
|
|
|
* Returns the array size. |
143
|
|
|
* |
144
|
|
|
* @return int the length |
145
|
|
|
*/ |
146
|
|
|
public function size() : int { |
147
|
|
|
return $this->size; |
148
|
|
|
} |
149
|
|
|
|
150
|
|
|
/** |
151
|
|
|
* Deletes the first node of the list and returns it. |
152
|
|
|
* |
153
|
|
|
* @return mixed the data. |
154
|
|
|
*/ |
155
|
|
|
public function shift() { |
156
|
|
|
return $this->delete(0); |
157
|
|
|
} |
158
|
|
|
|
159
|
|
|
/** |
160
|
|
|
* Returns array stored in the data attribute. |
161
|
|
|
* |
162
|
|
|
* @return array data stored in all nodes. |
163
|
|
|
*/ |
164
|
|
|
public function toArray() : array { |
165
|
|
|
return $this->data; |
166
|
|
|
} |
167
|
|
|
|
168
|
|
|
/** |
169
|
|
|
* Reset the cursor position. |
170
|
|
|
*/ |
171
|
|
|
public function rewind() { |
172
|
|
|
$this->position = 0; |
173
|
|
|
$this->current = $this->data[$this->position]; |
174
|
|
|
} |
175
|
|
|
|
176
|
|
|
/** |
177
|
|
|
* Returns the current node data. |
178
|
|
|
* |
179
|
|
|
* @return mixed |
180
|
|
|
*/ |
181
|
|
|
public function current() { |
182
|
|
|
return $this->current; |
183
|
|
|
} |
184
|
|
|
|
185
|
|
|
/** |
186
|
|
|
* Key or index that indicates the cursor position. |
187
|
|
|
* |
188
|
|
|
* @return integer The current position. |
189
|
|
|
*/ |
190
|
|
|
public function key() { |
191
|
|
|
return $this->position; |
192
|
|
|
} |
193
|
|
|
|
194
|
|
|
/** |
195
|
|
|
* Move the cursor to the next node and increments the |
196
|
|
|
* position counter. |
197
|
|
|
*/ |
198
|
|
|
public function next() { |
199
|
|
|
++$this->position; |
200
|
|
|
$this->current = $this->data[$this->position]; |
201
|
|
|
} |
202
|
|
|
|
203
|
|
|
/** |
204
|
|
|
* Returns if the current pointer position is valid. |
205
|
|
|
* |
206
|
|
|
* @return boolean true if pointer is not last, else false. |
207
|
|
|
*/ |
208
|
|
|
public function valid() { |
209
|
|
|
return $this->position < $this->size; |
210
|
|
|
} |
211
|
|
|
|
212
|
|
|
/** |
213
|
|
|
* Binds to count() method. This is equal to make $this->list->size(). |
214
|
|
|
* |
215
|
|
|
* @return integer the list size. 0 if it is empty. |
216
|
|
|
*/ |
217
|
|
|
public function count() { |
218
|
|
|
return $this->size; |
219
|
|
|
} |
220
|
|
|
|
221
|
|
|
public function offsetSet($offset, $valor) { |
222
|
|
|
//TODO |
223
|
|
|
/* |
|
|
|
|
224
|
|
|
if (is_null($offset)) { |
225
|
|
|
// $this->contenedor[] = $valor; |
226
|
|
|
} else { |
227
|
|
|
// $this->contenedor[$offset] = $valor; |
228
|
|
|
} |
229
|
|
|
*/ |
230
|
|
|
} |
231
|
|
|
|
232
|
|
|
public function offsetExists($offset) { |
233
|
|
|
//TODO |
234
|
|
|
// return false; |
235
|
|
|
// return isset($this->contenedor[$offset]); |
|
|
|
|
236
|
|
|
} |
237
|
|
|
|
238
|
|
|
public function offsetUnset($offset) { |
239
|
|
|
//TODO |
240
|
|
|
// unset($this->contenedor[$offset]); |
|
|
|
|
241
|
|
|
} |
242
|
|
|
|
243
|
|
|
public function offsetGet($offset) { |
244
|
|
|
//TODO |
245
|
|
|
// return false; |
246
|
|
|
// return isset($this->contenedor[$offset]) ? $this->contenedor[$offset] : null; |
|
|
|
|
247
|
|
|
} |
248
|
|
|
} |
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.
The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.
This check looks for comments that seem to be mostly valid code and reports them.