Skip to content
Permalink
Browse files

Add avg and median methods to CollectionTrait and Interface

  • Loading branch information...
Iandenh committed Jul 18, 2017
1 parent 341c6da commit f1bfd8b6e87e9f41267288285fef9e36942b35ce
@@ -285,6 +285,63 @@ public function max($callback, $type = SORT_NUMERIC);
*/
public function min($callback, $type = SORT_NUMERIC);
/**
* Returns the average of all the values extracted with $matcher
* or of this collection.
*
* ### Example:
*
* ```
* $items = [
* ['invoice' => ['total' => 100]],
* ['invoice' => ['total' => 200]]
* ];
*
* $total = (new Collection($items))->avg('invoice.total');
*
* // Total: 150
*
* $total = (new Collection([1, 2, 3]))->avg();
* // Total: 2
* ```
*
* @param string|callable|null $matcher The property name to sum or a function
* If no value is passed, an identity function will be used.
* that will return the value of the property to sum.
* @return float|int|null
*/
public function avg($matcher = null);
/**
* Returns the median of all the values extracted with $matcher
* or of this collection.
*
* ### Example:
*
* ```
* $items = [
* ['invoice' => ['total' => 400]],
* ['invoice' => ['total' => 500]]
* ['invoice' => ['total' => 100]]
* ['invoice' => ['total' => 333]]
* ['invoice' => ['total' => 200]]
* ];
*
* $total = (new Collection($items))->median('invoice.total');
*
* // Total: 333
*
* $total = (new Collection([1, 2, 3, 4]))->median();
* // Total: 2.5
* ```
*
* @param string|callable|null $matcher The property name to sum or a function
* If no value is passed, an identity function will be used.
* that will return the value of the property to sum.
* @return float|int|null
*/
public function median($matcher = null);
/**
* Returns a sorted iterator out of the elements in this collection,
* ranked in ascending order by the results of running each value through a
@@ -190,6 +190,54 @@ public function min($callback, $type = SORT_NUMERIC)
return (new SortIterator($this->unwrap(), $callback, SORT_ASC, $type))->first();
}
/**
* {@inheritDoc}
*/
public function avg($matcher = null)
{
$iterator = $this->unwrap();
$count = $iterator instanceof Countable ?
count($iterator) :
iterator_count($iterator);
if ($count === 0) {
return null;
}
return $this->sumOf($matcher) / $count;
}
/**
* {@inheritDoc}
*/
public function median($matcher = null)
{
$iterator = $this->unwrap();
$count = $iterator instanceof Countable ?
count($iterator) :
iterator_count($iterator);
if ($count === 0) {
return null;
}
$middle = (int)($count / 2);
$elements = $this;
if ($matcher != null) {
$elements = $elements->extract($matcher);
}
$values = $elements->toArray();
sort($values);
if ($count % 2) {
return $values[$middle];
}
return (new static([
$values[$middle - 1], $values[$middle],
]))->avg();
}
/**
* {@inheritDoc}
*/
@@ -59,6 +59,60 @@ public function testArrayIsWrapped()
$this->assertEquals($items, iterator_to_array($collection));
}
/**
* Tests that it is possible to convert an array into a collection
*
* @return void
*/
public function testAvg()
{
$items = [1, 2, 3];
$collection = new Collection($items);
$this->assertEquals(2, $collection->avg());
$collection = new Collection([]);
$this->assertNull($collection->avg());
$items = [['foo' => 1], ['foo' => 2], ['foo' => 3]];
$collection = new Collection($items);
$this->assertEquals(2, $collection->avg('foo'));
$items = [
['invoice' => ['total' => 100]],
['invoice' => ['total' => 200]]
];
$this->assertEquals(150, (new Collection($items))->avg('invoice.total'));
}
/**
* Tests that it is possible to convert an array into a collection
*
* @return void
*/
public function testMedian()
{
$items = [5, 2, 4];
$collection = new Collection($items);
$this->assertEquals(4, $collection->median());
$collection = new Collection([]);
$this->assertNull($collection->median());
$items = [1, 2, 3, 4];
$collection = new Collection($items);
$this->assertEquals(2.5, $collection->median());
$items = [
['invoice' => ['total' => 400]],
['invoice' => ['total' => 500]],
['invoice' => ['total' => 200]],
['invoice' => ['total' => 100]],
['invoice' => ['total' => 333]]
];
$this->assertEquals(333, (new Collection($items))->median('invoice.total'));
}
/**
* Tests that it is possible to convert an iterator into a collection
*

0 comments on commit f1bfd8b

Please sign in to comment.
You can’t perform that action at this time.