Skip to content

Commit

Permalink
Add LazyCollection@remember method
Browse files Browse the repository at this point in the history
  • Loading branch information
JosephSilber committed Oct 28, 2019
1 parent 0634709 commit 54ae1cc
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 0 deletions.
36 changes: 36 additions & 0 deletions src/Illuminate/Support/LazyCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,42 @@ public function eager()
return new static($this->all());
}

/**
* Cache values as they're enumerated.
*
* @return static
*/
public function remember()
{
$iterator = $this->getIterator();

$iteratorIndex = 0;

$cache = [];

return new static(function () use ($iterator, &$iteratorIndex, &$cache) {
for ($index = 0; true; $index++) {
if (array_key_exists($index, $cache)) {
yield $cache[$index][0] => $cache[$index][1];

continue;
}

if ($iteratorIndex < $index) {
$iterator->next();

$iteratorIndex++;
}

if (! $iterator->valid()) break;

$cache[$index] = [$iterator->key(), $iterator->current()];

yield $cache[$index][0] => $cache[$index][1];
}
});
}

/**
* Get the average value of a given key.
*
Expand Down
21 changes: 21 additions & 0 deletions tests/Support/SupportLazyCollectionIsLazyTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -763,6 +763,27 @@ public function testRejectIsLazy()
});
}

public function testRememberIsLazy()
{
$this->assertDoesNotEnumerate(function ($collection) {
$collection->remember();
});

$this->assertEnumeratesOnce(function ($collection) {
$collection = $collection->remember();

$collection->all();
$collection->all();
});

$this->assertEnumerates(5, function ($collection) {
$collection = $collection->remember();

$collection->take(5)->all();
$collection->take(5)->all();
});
}

public function testReplaceIsLazy()
{
$this->assertDoesNotEnumerate(function ($collection) {
Expand Down
60 changes: 60 additions & 0 deletions tests/Support/SupportLazyCollectionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,66 @@ public function testEager()
$this->assertSame([1, 2, 3, 4, 5], $data->all());
}

public function testRemember()
{
$source = [1, 2, 3, 4];

$collection = LazyCollection::make(function () use (&$source) {
yield from $source;
})->remember();

$this->assertSame([1, 2, 3, 4], $collection->all());

$source = [];

$this->assertSame([1, 2, 3, 4], $collection->all());
}

public function testRememberWithTwoRunners()
{
$source = [1, 2, 3, 4];

$collection = LazyCollection::make(function () use (&$source) {
yield from $source;
})->remember();

$a = $collection->getIterator();
$b = $collection->getIterator();

$this->assertEquals(1, $a->current());
$this->assertEquals(1, $b->current());

$b->next();

$this->assertEquals(1, $a->current());
$this->assertEquals(2, $b->current());

$b->next();

$this->assertEquals(1, $a->current());
$this->assertEquals(3, $b->current());

$a->next();

$this->assertEquals(2, $a->current());
$this->assertEquals(3, $b->current());

$a->next();

$this->assertEquals(3, $a->current());
$this->assertEquals(3, $b->current());

$a->next();

$this->assertEquals(4, $a->current());
$this->assertEquals(3, $b->current());

$b->next();

$this->assertEquals(4, $a->current());
$this->assertEquals(4, $b->current());
}

public function testTapEach()
{
$data = LazyCollection::times(10);
Expand Down

0 comments on commit 54ae1cc

Please sign in to comment.