Skip to content
This repository was archived by the owner on Dec 28, 2023. It is now read-only.

Commit d118f4c

Browse files
committed
Improve IteratorProvider::cycle() implement
1 parent 4144d6c commit d118f4c

File tree

3 files changed

+80
-16
lines changed

3 files changed

+80
-16
lines changed

benchmarks/CycleEvent.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
namespace Emonkak\Collection\Benchmarks;
4+
5+
use Athletic\AthleticEvent;
6+
use Emonkak\Collection\Collection;
7+
8+
class CycleEvent extends AthleticEvent
9+
{
10+
use CollectionBenchmark;
11+
12+
public function setUp()
13+
{
14+
$this->data = Collection::from(range(0, 10));
15+
}
16+
17+
protected function execute($xs)
18+
{
19+
foreach ($xs->cycle(100) as $x);
20+
}
21+
}

src/Iterator/CycleIterator.php

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
3+
namespace Emonkak\Collection\Iterator;
4+
5+
class CycleIterator implements \Iterator
6+
{
7+
private $it;
8+
private $n;
9+
private $i;
10+
11+
public function __construct(\Iterator $it, $n)
12+
{
13+
$this->it = $it;
14+
$this->n = $n;
15+
}
16+
17+
public function current()
18+
{
19+
return $this->it->current();
20+
}
21+
22+
public function key()
23+
{
24+
return $this->it->key();
25+
}
26+
27+
public function next()
28+
{
29+
$this->it->next();
30+
31+
if (!$this->it->valid()) {
32+
$this->i++;
33+
$this->it->rewind();
34+
}
35+
}
36+
37+
public function rewind()
38+
{
39+
$this->i = 0;
40+
$this->it->rewind();
41+
}
42+
43+
public function valid()
44+
{
45+
return $this->i < $this->n && $this->it->valid();
46+
}
47+
}

src/Provider/IteratorProvider.php

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use Emonkak\Collection\Comparer\EqualityComparer;
66
use Emonkak\Collection\Iterator\ConcatMapIterator;
7+
use Emonkak\Collection\Iterator\CycleIterator;
78
use Emonkak\Collection\Iterator\DropWhileIterator;
89
use Emonkak\Collection\Iterator\FlattenIterator;
910
use Emonkak\Collection\Iterator\GroupJoinIterator;
@@ -45,8 +46,8 @@ public function map($xs, callable $valueSelector, callable $keySelector)
4546
*/
4647
public function concatMap($xs, callable $selector)
4748
{
48-
$inner = new ConcatMapIterator(Iterators::create($xs), $selector);
49-
return new \RecursiveIteratorIterator($inner);
49+
$it = new ConcatMapIterator(Iterators::create($xs), $selector);
50+
return new \RecursiveIteratorIterator($it);
5051
}
5152

5253
/**
@@ -186,8 +187,8 @@ public function dropWhile($xs, callable $predicate)
186187
*/
187188
public function flatten($xs, $shallow)
188189
{
189-
$inner = new FlattenIterator(Iterators::create($xs), $shallow);
190-
return new \RecursiveIteratorIterator($inner);
190+
$it = new FlattenIterator(Iterators::create($xs), $shallow);
191+
return new \RecursiveIteratorIterator($it);
191192
}
192193

193194
/**
@@ -243,16 +244,11 @@ public function concat($xss)
243244
*/
244245
public function cycle($xs, $n)
245246
{
246-
$inner = Iterators::create($xs);
247-
if ($n === null) {
248-
return new \InfiniteIterator($inner);
247+
$it = Iterators::create($xs);
248+
if ($n !== null) {
249+
return new CycleIterator($it, $n);
249250
} else {
250-
// TODO: Implement CycleIterator
251-
$it = new \AppendIterator();
252-
while ($n-- > 0) {
253-
$it->append($inner);
254-
}
255-
return $it;
251+
return new \InfiniteIterator($it);
256252
}
257253
}
258254

@@ -269,10 +265,10 @@ public function range($start, $stop, $step)
269265
*/
270266
public function repeat($value, $n)
271267
{
272-
if ($n === null) {
273-
return new \InfiniteIterator(new \ArrayIterator([$value]));
274-
} else {
268+
if ($n !== null) {
275269
return new RepeatIterator($value, $n);
270+
} else {
271+
return new \InfiniteIterator(new \ArrayIterator([$value]));
276272
}
277273
}
278274

0 commit comments

Comments
 (0)