Adding convenience method Set::apply().

This commit is contained in:
jperras 2009-09-23 21:03:09 -04:00
parent 1ed4a63416
commit b2eb1882a4
2 changed files with 84 additions and 0 deletions

View file

@ -1137,6 +1137,40 @@ class Set extends Object {
return $sorted;
}
/**
* Allows the application of a callback method to elements of an
* array extracted by a Set::extract() compatible path.
*
* @param string $path A Set-compatible path to the array value
* @param array $data
* @param mixed $callback Callback method to be applied to extracted data.
* See http://ca2.php.net/manual/en/language.pseudo-types.php#language.types.callback for examples
* of callback formats.
* @param array $options
* @return mixed Result of the callback when applied to extracted data
*
*/
function apply($path, $data, $callback, $options = array()) {
$defaults = array('type' => 'pass');
$options = array_merge($defaults, $options);
$extracted = Set::extract($path, $data);
if ($options['type'] === 'map') {
$result = array_map($callback, &$extracted);
} elseif ($options['type'] === 'reduce') {
$result = array_reduce(&$extracted, $callback);
} elseif ($options['type'] === 'pass') {
$result = call_user_func_array($callback, array($extracted));
} else {
return null;
}
return $result;
}
/**
* Deprecated, Set class should be called statically
*

View file

@ -2402,6 +2402,56 @@ class SetTest extends CakeTestCase {
$this->assertIdentical($result, $array1+$array2);
}
/**
* testSetApply method
* @access public
* @return void
*
*/
function testApply() {
$data = array(
array('Movie' => array('id' => 1, 'title' => 'movie 3', 'rating' => 5)),
array('Movie' => array('id' => 1, 'title' => 'movie 1', 'rating' => 1)),
array('Movie' => array('id' => 1, 'title' => 'movie 2', 'rating' => 3))
);
$result = Set::apply('/Movie/rating', $data, 'array_sum');
$expected = 9;
$this->assertEqual($result, $expected);
$result = Set::apply('/Movie/rating', $data, 'array_product');
$expected = 15;
$this->assertEqual($result, $expected);
$result = Set::apply('/Movie/title', $data, 'ucfirst', array('type' => 'map'));
$expected = array('Movie 3', 'Movie 1', 'Movie 2');
$this->assertEqual($result, $expected);
$result = Set::apply('/Movie/title', $data, 'strtoupper', array('type' => 'map'));
$expected = array('MOVIE 3', 'MOVIE 1', 'MOVIE 2');
$this->assertEqual($result, $expected);
$result = Set::apply('/Movie/rating', $data, array('self', '_method'), array('type' => 'reduce'));
$expected = 9;
$this->assertEqual($result, $expected);
$result = Set::apply('/Movie/rating', $data, 'strtoupper', array('type' => 'non existing type'));
$expected = null;
$this->assertEqual($result, $expected);
}
/**
* Helper method to test Set::apply()
*
* @access protected
* @return void
*/
function _method($val1, $val2) {
$val1 += $val2;
return $val1;
}
/**
* testXmlSetReverse method
*