1
|
|
|
<?php namespace Mbh\Collection\Traits; |
2
|
|
|
|
3
|
|
|
use Mbh\Collection\Interfaces\Collection as CollectionInterface; |
4
|
|
|
use Mbh\Collection\Interfaces\Sequenceable as SequenceableInterface; |
5
|
|
|
use Mbh\Collection\FixedArray; |
6
|
|
|
use Mbh\Collection\CallbackHeap; |
7
|
|
|
use Mbh\Iterator\SliceIterator; |
8
|
|
|
use Mbh\Iterator\ConcatIterator; |
9
|
|
|
use SplFixedArray; |
10
|
|
|
use SplHeap; |
11
|
|
|
use SplStack; |
12
|
|
|
use LimitIterator; |
13
|
|
|
use Iterator; |
14
|
|
|
use ArrayAccess; |
15
|
|
|
use Countable; |
16
|
|
|
use CallbackFilterIterator; |
17
|
|
|
use JsonSerializable; |
18
|
|
|
use RuntimeException; |
19
|
|
|
use Traversable; |
20
|
|
|
use ReflectionClass; |
21
|
|
|
use UnderflowException; |
22
|
|
|
use OutOfRangeException; |
23
|
|
|
|
24
|
|
|
/** |
25
|
|
|
* MBHFramework |
26
|
|
|
* |
27
|
|
|
* @link https://github.com/MBHFramework/mbh-framework |
28
|
|
|
* @copyright Copyright (c) 2017 Ulises Jeremias Cornejo Fandos |
29
|
|
|
* @license https://github.com/MBHFramework/mbh-framework/blob/master/LICENSE (MIT License) |
30
|
|
|
*/ |
31
|
|
|
|
32
|
|
|
trait Functional |
33
|
|
|
{ |
34
|
|
|
use Sort { |
35
|
|
|
Sort::heapSort as heapSortWithCallback; |
36
|
|
|
Sort::heapSorted as heapSortedWithCallback; |
37
|
|
|
} |
38
|
|
|
|
39
|
|
|
protected function getSplFixedArrayAndSize() |
40
|
|
|
{ |
41
|
|
|
$count = $this->count(); |
42
|
|
|
return [new SplFixedArray($count), $count]; |
43
|
|
|
} |
44
|
|
|
|
45
|
|
|
/** |
46
|
|
|
* @inheritDoc |
47
|
|
|
*/ |
48
|
|
View Code Duplication |
public function map(callable $callback) |
|
|
|
|
49
|
|
|
{ |
50
|
|
|
list($sfa, $count) = $this->getSplFixedArrayAndSize(); |
51
|
|
|
|
52
|
|
|
for ($i = 0; $i < $count; $i++) { |
53
|
|
|
$sfa[$i] = $callback($this[$i], $i, $this); |
54
|
|
|
} |
55
|
|
|
|
56
|
|
|
return new static($sfa); |
57
|
|
|
} |
58
|
|
|
|
59
|
|
|
/** |
60
|
|
|
* @inheritDoc |
61
|
|
|
*/ |
62
|
|
|
public function walk(callable $callback) |
63
|
|
|
{ |
64
|
|
|
foreach ($this as $i => $elem) { |
65
|
|
|
$callback($elem, $i, $this); |
66
|
|
|
} |
67
|
|
|
|
68
|
|
|
return $this; |
69
|
|
|
} |
70
|
|
|
|
71
|
|
|
/** |
72
|
|
|
* @inheritDoc |
73
|
|
|
*/ |
74
|
|
View Code Duplication |
public function filter(callable $callback) |
|
|
|
|
75
|
|
|
{ |
76
|
|
|
list($sfa, $count) = $this->getSplFixedArrayAndSize(); |
77
|
|
|
|
78
|
|
|
$newCount = 0; |
79
|
|
|
foreach ($this as $elem) { |
80
|
|
|
if ($callback($elem)) { |
81
|
|
|
$sfa[$newCount++] = $elem; |
82
|
|
|
} |
83
|
|
|
} |
84
|
|
|
|
85
|
|
|
$sfa->setSize($newCount); |
86
|
|
|
return new static($sfa); |
87
|
|
|
} |
88
|
|
|
|
89
|
|
|
/** |
90
|
|
|
* @inheritDoc |
91
|
|
|
*/ |
92
|
|
|
public function reduce(callable $callback, $accumulator = null) |
93
|
|
|
{ |
94
|
|
|
foreach ($this as $i => $elem) { |
95
|
|
|
$accumulator = $callback($accumulator, $elem, $i, $this); |
96
|
|
|
} |
97
|
|
|
|
98
|
|
|
return $accumulator; |
99
|
|
|
} |
100
|
|
|
|
101
|
|
|
/** |
102
|
|
|
* @inheritDoc |
103
|
|
|
*/ |
104
|
|
|
public function join(string $token = ',', string $secondToken = null): string |
105
|
|
|
{ |
106
|
|
|
$str = ""; |
107
|
|
|
if ($secondToken !== null) { |
108
|
|
|
foreach ($this as $i => $elem) { |
109
|
|
|
$str .= $token . (string) $elem . $secondToken; |
110
|
|
|
} |
111
|
|
|
} else { |
112
|
|
|
$this->rewind(); |
113
|
|
|
while ($this->valid()) { |
114
|
|
|
$str .= (string) $this->current(); |
115
|
|
|
$this->next(); |
116
|
|
|
if ($this->valid()) { |
117
|
|
|
$str .= $token; |
118
|
|
|
} |
119
|
|
|
} |
120
|
|
|
} |
121
|
|
|
|
122
|
|
|
return $str; |
123
|
|
|
} |
124
|
|
|
|
125
|
|
|
/** |
126
|
|
|
* @inheritDoc |
127
|
|
|
*/ |
128
|
|
|
public function slice(int $begin = 0, int $end = null) |
129
|
|
|
{ |
130
|
|
|
$it = new SliceIterator($this->getMainTraversable(), $begin, $end); |
131
|
|
|
return static::fromArray($it->toArray()); |
132
|
|
|
} |
133
|
|
|
|
134
|
|
|
/** |
135
|
|
|
* @inheritDoc |
136
|
|
|
*/ |
137
|
|
|
public function concat(...$args) |
138
|
|
|
{ |
139
|
|
|
array_unshift($args, $this); |
140
|
|
|
|
141
|
|
|
// Concat this iterator, and variadic args |
142
|
|
|
$class = new ReflectionClass('Mbh\Iterator\ConcatIterator'); |
143
|
|
|
$concatIt = $class->newInstanceArgs($args); |
144
|
|
|
|
145
|
|
|
// Create as new immutable's iterator |
146
|
|
|
return static::fromArray($concatIt->toArray()); |
147
|
|
|
} |
148
|
|
|
|
149
|
|
|
/** |
150
|
|
|
* @inheritDoc |
151
|
|
|
*/ |
152
|
|
|
public function find(callable $callback) |
153
|
|
|
{ |
154
|
|
|
foreach ($this as $i => $elem) { |
155
|
|
|
if ($callback($elem, $i, $this)) { |
156
|
|
|
return $elem; |
157
|
|
|
} |
158
|
|
|
} |
159
|
|
|
} |
160
|
|
|
|
161
|
|
|
/** |
162
|
|
|
* @inheritDoc |
163
|
|
|
*/ |
164
|
|
|
public function search($value) |
165
|
|
|
{ |
166
|
|
|
foreach ($this as $i => $elem) { |
167
|
|
|
if ($value === $elem) { |
168
|
|
|
return $i; |
169
|
|
|
} |
170
|
|
|
} |
171
|
|
|
} |
172
|
|
|
|
173
|
|
|
/** |
174
|
|
|
* @inheritDoc |
175
|
|
|
*/ |
176
|
|
|
public function sort(callable $callback = null) |
177
|
|
|
{ |
178
|
|
|
if ($callback) { |
179
|
|
|
return $this->mergeSort($callback); |
180
|
|
|
} |
181
|
|
|
|
182
|
|
|
return $this->arraySort(); |
183
|
|
|
} |
184
|
|
|
|
185
|
|
|
/** |
186
|
|
|
* @inheritDoc |
187
|
|
|
*/ |
188
|
|
|
public function sorted(callable $callback = null) |
189
|
|
|
{ |
190
|
|
|
$copy = FixedArray::fromItems($this->copy()); |
191
|
|
|
|
192
|
|
|
if ($callback) { |
193
|
|
|
$copy->mergeSort($callback); |
194
|
|
|
} |
195
|
|
|
|
196
|
|
|
$copy->arraySort(); |
197
|
|
|
|
198
|
|
|
return static::fromItems($copy); |
199
|
|
|
} |
200
|
|
|
|
201
|
|
|
/** |
202
|
|
|
* @inheritDoc |
203
|
|
|
*/ |
204
|
|
|
public function heapSorted(SplHeap $heap) |
205
|
|
|
{ |
206
|
|
|
return $this->copy()->heapSort($heap); |
207
|
|
|
} |
208
|
|
|
|
209
|
|
|
/** |
210
|
|
|
* @inheritDoc |
211
|
|
|
*/ |
212
|
|
|
public function heapSort(SplHeap $heap) |
213
|
|
|
{ |
214
|
|
|
foreach ($this as $item) { |
215
|
|
|
$heap->insert($item); |
216
|
|
|
} |
217
|
|
|
|
218
|
|
|
$this->setTraversable(static::fromItems($heap)); |
219
|
|
|
|
220
|
|
|
return $this; |
221
|
|
|
} |
222
|
|
|
|
223
|
|
|
abstract public static function fromItems(Traversable $array); |
224
|
|
|
|
225
|
|
|
abstract protected function getMainTraversable(): Traversable; |
226
|
|
|
|
227
|
|
|
abstract public function count(): int; |
228
|
|
|
|
229
|
|
|
abstract public function current(); |
230
|
|
|
|
231
|
|
|
abstract public function next(); |
232
|
|
|
|
233
|
|
|
abstract public function rewind(); |
234
|
|
|
|
235
|
|
|
abstract public function valid(); |
236
|
|
|
} |
237
|
|
|
|
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.