Skip to content

Commit 3049b5d

Browse files
aleksandr-rudoAleksandr Rudo
and
Aleksandr Rudo
authored
PHPLIB-609: Allow CachingIterator to handle Iterators with non-unique keys (#896)
* Adding new test for non-unique keys support in CachingIterator. Co-authored-by: Aleksandr Rudo <[email protected]>
1 parent 22e84ad commit 3049b5d

File tree

2 files changed

+45
-4
lines changed

2 files changed

+45
-4
lines changed

src/Model/CachingIterator.php

+14-4
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525

2626
use function count;
2727
use function current;
28-
use function key;
2928
use function next;
3029
use function reset;
3130

@@ -40,6 +39,9 @@
4039
*/
4140
class CachingIterator implements Countable, Iterator
4241
{
42+
private const FIELD_KEY = 0;
43+
private const FIELD_VALUE = 1;
44+
4345
/** @var array */
4446
private $items = [];
4547

@@ -87,7 +89,9 @@ public function count()
8789
#[ReturnTypeWillChange]
8890
public function current()
8991
{
90-
return current($this->items);
92+
$currentItem = current($this->items);
93+
94+
return $currentItem !== false ? $currentItem[self::FIELD_VALUE] : false;
9195
}
9296

9397
/**
@@ -97,7 +101,9 @@ public function current()
97101
#[ReturnTypeWillChange]
98102
public function key()
99103
{
100-
return key($this->items);
104+
$currentItem = current($this->items);
105+
106+
return $currentItem !== false ? $currentItem[self::FIELD_KEY] : null;
101107
}
102108

103109
/**
@@ -165,6 +171,10 @@ private function storeCurrentItem()
165171
return;
166172
}
167173

168-
$this->items[$this->iterator->key()] = $this->iterator->current();
174+
// Storing a new item in the internal cache
175+
$this->items[] = [
176+
self::FIELD_KEY => $this->iterator->key(),
177+
self::FIELD_VALUE => $this->iterator->current(),
178+
];
169179
}
170180
}

tests/Model/CachingIteratorTest.php

+31
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,26 @@ public function rewind(): void
152152
$this->assertCount(1, $iterator);
153153
}
154154

155+
public function testCountNonUniqueKeys(): void
156+
{
157+
$iterator = new CachingIterator($this->getNonUniqueTraversable([1, 2, 3]));
158+
$this->assertCount(3, $iterator);
159+
}
160+
161+
public function testIterationNonUniqueKeys(): void
162+
{
163+
$iterator = new CachingIterator($this->getNonUniqueTraversable([1, 2, 3]));
164+
165+
$expectedItem = 1;
166+
167+
foreach ($iterator as $key => $item) {
168+
$this->assertSame(0, $key);
169+
$this->assertSame($expectedItem++, $item);
170+
}
171+
172+
$this->assertFalse($iterator->valid());
173+
}
174+
155175
private function getTraversable($items)
156176
{
157177
foreach ($items as $item) {
@@ -162,4 +182,15 @@ private function getTraversable($items)
162182
}
163183
}
164184
}
185+
186+
private function getNonUniqueTraversable($items)
187+
{
188+
foreach ($items as $item) {
189+
if ($item instanceof Exception) {
190+
throw $item;
191+
} else {
192+
yield 0 => $item;
193+
}
194+
}
195+
}
165196
}

0 commit comments

Comments
 (0)