Skip to content

Commit

Permalink
Implemented Collection::map()
Browse files Browse the repository at this point in the history
  • Loading branch information
lorenzo committed Dec 25, 2013
1 parent a8cd64c commit e6c2e30
Show file tree
Hide file tree
Showing 6 changed files with 163 additions and 3 deletions.
2 changes: 0 additions & 2 deletions Cake/ORM/BufferedResultSet.php
@@ -1,7 +1,5 @@
<?php
/**
* PHP Version 5.4
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
Expand Down
15 changes: 15 additions & 0 deletions Cake/Test/TestCase/Utility/CollectionTest.php
Expand Up @@ -202,4 +202,19 @@ public function testContains() {
$this->assertFalse($collection->contains('2'));
}

/**
* Tests map
*
* @return void
*/
public function testMap() {
$items = ['a' => 1, 'b' => 2, 'c' => 3];
$collection = new Collection($items);
$map = $collection->map(function($v, $k, $it) use ($collection) {
$this->assertSame($collection, $it);
return $v * $v;
});
$this->assertInstanceOf('\Cake\Utility\Iterator\ReplaceIterator', $map);
$this->assertEquals(['a' => 1, 'b' => 4, 'c' => 9], iterator_to_array($map));
}
}
51 changes: 51 additions & 0 deletions Cake/Test/TestCase/Utility/Iterator/ReplaceIteratorTest.php
@@ -0,0 +1,51 @@
<?php
/**
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @since CakePHP(tm) v 3.0.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
namespace Cake\Test\TestCase\Utility\Iterator;

use Cake\TestSuite\TestCase;
use Cake\Utility\Iterator\ReplaceIterator;

/**
* ReplaceIterator Test
*
*/
class ReplaceIteratorTest extends TestCase {

/**
* Tests that the iterator works correctly
*
* @return void
*/
public function testReplace() {
$items = new \ArrayIterator([1, 2, 3]);
$callable = $this->getMock('stdClass', ['__invoke']);
$callable->expects($this->at(0))
->method('__invoke')
->with(1, 0, $items)
->will($this->returnValue(1));
$callable->expects($this->at(1))
->method('__invoke')
->with(2, 1, $items)
->will($this->returnValue(4));
$callable->expects($this->at(2))
->method('__invoke')
->with(3, 2, $items)
->will($this->returnValue(9));

$map = new ReplaceIterator($items, $callable);
$this->assertEquals([1, 4, 9], iterator_to_array($map));
}

}
34 changes: 34 additions & 0 deletions Cake/Utility/Collection.php
Expand Up @@ -16,6 +16,7 @@

use ArrayIterator;
use Cake\Utility\Iterator\FilterIterator;
use Cake\Utility\Iterator\ReplaceIterator;
use InvalidArgumentException;
use IteratorIterator;

Expand Down Expand Up @@ -191,10 +192,43 @@ public function contains($value) {
return false;
}

/**
* Creates an iterator from another iterator that will modify each of the values
* by converting them using a callback function.
*/

/**
* Returns another collection after modifying each of the values in this one using
* the provided callable.
*
* Each time the callback is executed it will receive the value of the element
* in the current iteration, the key of the element and this collection as
* arguments, in that order.
*
* ##Example:
*
* Getting a collection of booleans where true indicates if a person is female:
*
* {{{
* $collection = (new Collection($people))->filter(function($person, $key) {
* return $person->sex === 'female';
* });
* }}}
*
* @param callable $c the method that will receive each of the elements and
* returns the new value for the key that is being iterated
* @return \Cake\Utility\Iterator\ReplaceIterator
*/
public function map(callable $c) {
return new ReplaceIterator($this, $c);
}

public function mapReduce(callable $map, callable $reduce) {
}


public function extract($property) {

}

public function max() {
Expand Down
4 changes: 3 additions & 1 deletion Cake/Utility/Iterator/FilterIterator.php
Expand Up @@ -19,7 +19,7 @@
use Iterator;

/**
* Create a filtered iterator from another iterator. The filtering is done by
* Creates a filtered iterator from another iterator. The filtering is done by
* passing a callback function to each of the elements and taking them out if
* it does not return true.
*/
Expand All @@ -33,6 +33,8 @@ class FilterIterator extends Collection {
* in the current iteration, the key of the element and the passed $items iterator
* as arguments, in that order.
*
* @param Iterator $items the items to be filtered
* @param callable $callback
* @return void
*/
public function __construct(Iterator $items, callable $callback) {
Expand Down
60 changes: 60 additions & 0 deletions Cake/Utility/Iterator/ReplaceIterator.php
@@ -0,0 +1,60 @@
<?php
/**
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @since CakePHP(tm) v 3.0.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
namespace Cake\Utility\Iterator;

use Cake\Utility\Collection;

/**
* Creates an iterator from another iterator that will modify each of the values
* by converting them using a callback function.
*/
class ReplaceIterator extends Collection {

/**
* The callback function to be used to modify each of the values
*
* @var callable
*/
protected $_callback;

/**
* Creates an iterator from another iterator that will modify each of the values
* by converting them using a callback function.
*
* Each time the callback is executed it will receive the value of the element
* in the current iteration, the key of the element and the passed $items iterator
* as arguments, in that order.
*
* @param array|\Traversable $items the items to be filtered
* @param callable $callback
* @return void
*/
public function __construct($items, callable $callback) {
$this->_callback = $callback;
parent::__construct($items);
}

/**
* Returns the value returned by the callback after passing the current value in
* the iteration
*
* @return mixed
*/
public function current() {
$callback = $this->_callback;
return $callback(parent::current(), $this->key(), $this->getInnerIterator());
}

}

0 comments on commit e6c2e30

Please sign in to comment.