Browse Source

Merge pull request #4640 from cakephp/3.0-sumby

Implemented Collection::sumOf()
Mark Story 11 years ago
parent
commit
915fb73bed
2 changed files with 49 additions and 0 deletions
  1. 31 0
      src/Collection/CollectionTrait.php
  2. 18 0
      tests/TestCase/Collection/CollectionTest.php

+ 31 - 0
src/Collection/CollectionTrait.php

@@ -516,6 +516,37 @@ trait CollectionTrait {
 	}
 
 /**
+ * Returns the total sum of all the values extracted with $matcher
+ * or of this collection.
+ *
+ * ###Example:
+ *
+ * {{{
+ * $items = [
+ *	['invoice' => ['total' => 100],
+ *	['invoice' => ['total' => 200]
+ * ];
+ *
+ * $total = (new Collection($items))->sumOf('invoice.total');
+ *
+ * // Total: 300
+ * }}}
+ *
+ * @param string|callable $matcher The property name to sum or a function
+ * that will return the value of the property to sum.
+ * @return float|int
+ */
+	public function sumOf($matcher) {
+		$callback = $this->_propertyExtractor($matcher);
+		$sum = 0;
+		foreach ($this as $k => $v) {
+			$sum += $callback($v, $k);
+		}
+
+		return $sum;
+	}
+
+/**
  * Returns a new collection with the elements placed in a random order,
  * this function does not preserve the original keys in the collection.
  *

+ 18 - 0
tests/TestCase/Collection/CollectionTest.php

@@ -934,4 +934,22 @@ class CollectionTest extends TestCase {
 		$this->assertEquals(range(1, 5), $collection->extract('id')->toArray(false));
 	}
 
+/**
+ * Tests the sumOf method
+ *
+ * @return void
+ */
+	public function testSumOf() {
+		$items = [
+			['invoice' => ['total' => 100]],
+			['invoice' => ['total' => 200]]
+		];
+		$this->assertEquals(300, (new Collection($items))->sumOf('invoice.total'));
+
+		$sum = (new Collection($items))->sumOf(function($v) {
+			return $v['invoice']['total'] * 2;
+		});
+		$this->assertEquals(600, $sum);
+	}
+
 }