From c5356372d799bccebaa156eb2cea5cb342645227 Mon Sep 17 00:00:00 2001 From: David Grudl Date: Sun, 10 Dec 2023 16:22:17 +0100 Subject: [PATCH] added MemoizingIterator --- src/Iterators/MemoizingIterator.php | 62 ++++++++++++++++++++++++++ tests/Iterators/MemoizingIterator.phpt | 58 ++++++++++++++++++++++++ 2 files changed, 120 insertions(+) create mode 100644 src/Iterators/MemoizingIterator.php create mode 100644 tests/Iterators/MemoizingIterator.phpt diff --git a/src/Iterators/MemoizingIterator.php b/src/Iterators/MemoizingIterator.php new file mode 100644 index 000000000..178f4deb7 --- /dev/null +++ b/src/Iterators/MemoizingIterator.php @@ -0,0 +1,62 @@ +index === 0) { + $this->inner->rewind(); + } else { + $this->index = 0; + } + } + + + public function current(): mixed + { + return $this->cache[$this->index][1] ?? null; + } + + + public function key(): mixed + { + return $this->cache[$this->index][0] ?? null; + } + + + public function next(): void + { + if (!isset($this->cache[++$this->index])) { + $this->inner->next(); + } + } + + + public function valid(): bool + { + if (!isset($this->cache[$this->index]) && $this->inner->valid()) { + $this->cache[$this->index] = [$this->inner->key(), $this->inner->current()]; + } + return isset($this->cache[$this->index]); + } +} diff --git a/tests/Iterators/MemoizingIterator.phpt b/tests/Iterators/MemoizingIterator.phpt new file mode 100644 index 000000000..5cf57845e --- /dev/null +++ b/tests/Iterators/MemoizingIterator.phpt @@ -0,0 +1,58 @@ + 'apple'; + yield ['b'] => ['banana']; + yield 'c' => 'cherry'; +} + + +test('iteration', function () { + $iterator = new MemoizingIterator(iterator()); + + $pairs = []; + foreach ($iterator as $key => $value) { + $pairs[] = [$key, $value]; + } + Assert::same( + [ + ['a', 'apple'], + [['b'], ['banana']], + ['c', 'cherry'], + ], + $pairs, + ); +}); + + +test('re-iteration', function () { + $iterator = new MemoizingIterator(iterator()); + + foreach ($iterator as $value); + + $pairs = []; + foreach ($iterator as $key => $value) { + $pairs[] = [$key, $value]; + } + Assert::same( + [ + ['a', 'apple'], + [['b'], ['banana']], + ['c', 'cherry'], + ], + $pairs, + ); +});