Skip to content

Commit

Permalink
Merge pull request #12541 from cakephp/collection-lazy
Browse files Browse the repository at this point in the history
Added a collection lazy() method
  • Loading branch information
markstory committed Sep 15, 2018
2 parents d0ad6a4 + 1c79759 commit fb90516
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 0 deletions.
10 changes: 10 additions & 0 deletions src/Collection/CollectionInterface.php
Expand Up @@ -802,6 +802,16 @@ public function jsonSerialize();
*/
public function compile($preserveKeys = true);

/**
* Returns a new collection where any operations chained after it are guaranteed
* to be run lazily. That is, elements will be yieleded one at a time.
*
* A lazy collection can only be iterated once. A second attempt results in an error.
*
* @return \Cake\Collection\CollectionInterface
*/
public function lazy();

/**
* Returns a new collection where the operations performed by this collection.
* No matter how many times the new collection is iterated, those operations will
Expand Down
14 changes: 14 additions & 0 deletions src/Collection/CollectionTrait.php
Expand Up @@ -685,6 +685,20 @@ public function compile($preserveKeys = true)
return new Collection($this->toArray($preserveKeys));
}

/**
* {@inheritDoc}
*/
public function lazy()
{
$generator = function () {
foreach ($this->unwrap() as $k => $v) {
yield $k => $v;
}
};

return new Collection($generator());
}

/**
* {@inheritDoc}
*
Expand Down
17 changes: 17 additions & 0 deletions tests/TestCase/Collection/CollectionTest.php
Expand Up @@ -2735,4 +2735,21 @@ public function testArrayIteratorExtend()
$this->assertTrue($newIterator->checkValues());
$this->assertCount(3, $newIterator->toArray());
}

/**
* Tests that elements in a lazy collection are not fetched immediately.
*
* @return void
*/
public function testLazy()
{
$items = ['a' => 1, 'b' => 2, 'c' => 3];
$collection = (new Collection($items))->lazy();
$callable = $this->getMockBuilder(\StdClass::class)
->setMethods(['__invoke'])
->getMock();

$callable->expects($this->never())->method('__invoke');
$collection->filter($callable)->filter($callable);
}
}

0 comments on commit fb90516

Please sign in to comment.