1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Pinq\Iterators\Standard; |
4
|
|
|
|
5
|
|
|
use Pinq\Iterators\Common; |
6
|
|
|
use Pinq\Iterators\Generators\IGenerator; |
7
|
|
|
|
8
|
|
|
/** |
9
|
|
|
* Iterator scheme using the extended iterator API. |
10
|
|
|
* Compatible with PHP 5.4.0. |
11
|
|
|
* |
12
|
|
|
* @author Elliot Levin <[email protected]> |
13
|
|
|
*/ |
14
|
|
|
class IteratorScheme extends Common\IteratorScheme |
15
|
|
|
{ |
16
|
|
|
public static function compatibleWith($phpVersion) |
17
|
|
|
{ |
18
|
|
|
return version_compare($phpVersion, '5.4.0', '>='); |
19
|
|
|
} |
20
|
|
|
|
21
|
|
|
public function createOrderedMap(\Traversable $iterator = null) |
22
|
|
|
{ |
23
|
|
|
return new OrderedMap($iterator === null ? null : $this->toIterator($iterator)); |
24
|
|
|
} |
25
|
|
|
|
26
|
|
|
public function createSet(\Traversable $iterator = null) |
27
|
|
|
{ |
28
|
|
|
return new Set($iterator === null ? null : $this->toIterator($iterator)); |
29
|
|
|
} |
30
|
|
|
|
31
|
|
|
public function walk(\Traversable $iterator, callable $function) |
32
|
|
|
{ |
33
|
|
|
$iterator = $this->adapter($iterator); |
34
|
|
|
$iterator->rewind(); |
35
|
|
|
|
36
|
|
|
while (($element = $iterator->fetch()) |
37
|
|
|
&& $function($element[1], $element[0]) !== false) { |
38
|
|
|
|
39
|
|
|
} |
40
|
|
|
} |
41
|
|
|
|
42
|
|
|
public function toArray(\Traversable $iterator) |
43
|
|
|
{ |
44
|
|
|
$iterator = $this->arrayCompatibleIterator($this->adapter($iterator)); |
45
|
|
|
$array = []; |
46
|
|
|
|
47
|
|
|
$iterator->rewind(); |
48
|
|
|
while ($element = $iterator->fetch()) { |
49
|
|
|
$array[$element[0]] =& $element[1]; |
50
|
|
|
} |
51
|
|
|
|
52
|
|
|
return $array; |
53
|
|
|
} |
54
|
|
|
|
55
|
|
|
/** |
56
|
|
|
* @param \Traversable $iterator |
57
|
|
|
* |
58
|
|
|
* @return IIterator |
59
|
|
|
*/ |
60
|
|
View Code Duplication |
public static function adapter(\Traversable $iterator) |
61
|
|
|
{ |
62
|
|
|
if ($iterator instanceof IIterator) { |
63
|
|
|
return $iterator; |
64
|
|
|
} elseif ($iterator instanceof IGenerator) { |
65
|
|
|
return new IGeneratorAdapter($iterator); |
66
|
|
|
} elseif ($iterator instanceof \ArrayIterator) { |
67
|
|
|
return new ArrayIteratorAdapter($iterator); |
68
|
|
|
} elseif ($iterator instanceof \IteratorAggregate) { |
69
|
|
|
return static::adapter($iterator->getIterator()); |
70
|
|
|
} else { |
71
|
|
|
return new IteratorAdapter($iterator); |
72
|
|
|
} |
73
|
|
|
} |
74
|
|
|
|
75
|
|
View Code Duplication |
public function arrayCompatibleIterator(\Traversable $iterator) |
|
|
|
|
76
|
|
|
{ |
77
|
|
|
$iterator = $this->adapter($iterator); |
78
|
|
|
if ($iterator->isArrayCompatible()) { |
79
|
|
|
return $iterator; |
80
|
|
|
} |
81
|
|
|
|
82
|
|
|
return new ArrayCompatibleIterator($this->adapter($iterator)); |
83
|
|
|
} |
84
|
|
|
|
85
|
|
|
public function adapterIterator(\Traversable $iterator) |
86
|
|
|
{ |
87
|
|
|
return $this->adapter($iterator); |
88
|
|
|
} |
89
|
|
|
|
90
|
|
|
public function arrayIterator(array $array) |
91
|
|
|
{ |
92
|
|
|
return new ArrayIterator($array); |
93
|
|
|
} |
94
|
|
|
|
95
|
|
|
public function emptyIterator() |
96
|
|
|
{ |
97
|
|
|
return new EmptyIterator(); |
98
|
|
|
} |
99
|
|
|
|
100
|
|
|
public function filterIterator(\Traversable $iterator, callable $predicate) |
101
|
|
|
{ |
102
|
|
|
return new FilterIterator($this->adapter($iterator), $predicate); |
103
|
|
|
} |
104
|
|
|
|
105
|
|
|
public function projectionIterator( |
106
|
|
|
\Traversable $iterator, |
107
|
|
|
callable $keyProjectionFunction = null, |
108
|
|
|
callable $valueProjectionFunction = null |
109
|
|
|
) { |
110
|
|
|
return new ProjectionIterator( |
111
|
|
|
$this->adapter($iterator), |
112
|
|
|
$keyProjectionFunction, |
113
|
|
|
$valueProjectionFunction); |
114
|
|
|
} |
115
|
|
|
|
116
|
|
|
public function reindexerIterator(\Traversable $iterator) |
117
|
|
|
{ |
118
|
|
|
return new ReindexedIterator($this->adapter($iterator)); |
119
|
|
|
} |
120
|
|
|
|
121
|
|
|
public function rangeIterator(\Traversable $iterator, $start, $amount) |
122
|
|
|
{ |
123
|
|
|
return new RangeIterator($this->adapter($iterator), $start, $amount); |
124
|
|
|
} |
125
|
|
|
|
126
|
|
|
public function groupedIterator( |
127
|
|
|
\Traversable $iterator, |
128
|
|
|
callable $groupKeyFunction, |
129
|
|
|
callable $traversableFactory |
130
|
|
|
) { |
131
|
|
|
return new GroupedIterator( |
132
|
|
|
$this->adapter($iterator), |
133
|
|
|
$groupKeyFunction, |
134
|
|
|
$traversableFactory); |
135
|
|
|
} |
136
|
|
|
|
137
|
|
|
public function orderedIterator(\Traversable $iterator, callable $function, $isAscending) |
138
|
|
|
{ |
139
|
|
|
return new OrderedIterator($this->adapter($iterator), $function, $isAscending); |
140
|
|
|
} |
141
|
|
|
|
142
|
|
|
public function joinIterator(\Traversable $outerIterator, \Traversable $innerIterator) |
143
|
|
|
{ |
144
|
|
|
return new UnfilteredJoinIterator( |
145
|
|
|
$this->adapter($outerIterator), |
146
|
|
|
$this->adapter($innerIterator)); |
147
|
|
|
} |
148
|
|
|
|
149
|
|
|
public function groupJoinIterator( |
150
|
|
|
\Traversable $outerIterator, |
151
|
|
|
\Traversable $innerIterator, |
152
|
|
|
callable $traversableFactory |
153
|
|
|
) { |
154
|
|
|
return new UnfilteredGroupJoinIterator( |
155
|
|
|
$this->adapter($outerIterator), |
156
|
|
|
$this->adapter($innerIterator), |
157
|
|
|
$traversableFactory); |
158
|
|
|
} |
159
|
|
|
|
160
|
|
|
protected function setOperationIterator(\Traversable $iterator, Common\SetOperations\ISetFilter $setFilter) |
161
|
|
|
{ |
162
|
|
|
return new SetOperationIterator($this->adapter($iterator), $setFilter); |
163
|
|
|
} |
164
|
|
|
|
165
|
|
|
protected function flattenedIteratorsIterator(\Traversable $iteratorsIterator) |
166
|
|
|
{ |
167
|
|
|
return new FlatteningIterator($this->adapter($iteratorsIterator)); |
168
|
|
|
} |
169
|
|
|
} |
170
|
|
|
|
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.