Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Adding convenience method Set::apply().

  • Loading branch information...
commit b2eb1882a4f5cfc2a0f7d74ce487c4528bbfb88d 1 parent 1ed4a63
@jperras jperras authored
Showing with 84 additions and 0 deletions.
  1. +34 −0 cake/libs/set.php
  2. +50 −0 cake/tests/cases/libs/set.test.php
View
34 cake/libs/set.php
@@ -1138,6 +1138,40 @@ function sort($data, $path, $dir) {
}
/**
+ * 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
50 cake/tests/cases/libs/set.test.php
@@ -2403,6 +2403,56 @@ function testPushDiff() {
}
/**
+ * 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
*
* @access public
Please sign in to comment.
Something went wrong with that request. Please try again.