Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Adding convenience method Set::apply().
  • Loading branch information
jperras committed Sep 24, 2009
1 parent 1ed4a63 commit b2eb188
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 0 deletions.
34 changes: 34 additions & 0 deletions cake/libs/set.php
Expand Up @@ -1137,6 +1137,40 @@ function sort($data, $path, $dir) {
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
*
Expand Down
50 changes: 50 additions & 0 deletions cake/tests/cases/libs/set.test.php
Expand Up @@ -2402,6 +2402,56 @@ function testPushDiff() {
$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
*
Expand Down

0 comments on commit b2eb188

Please sign in to comment.