Add `sum()` and `sumBy()`.
This commit is contained in:
parent
cf8092f6d2
commit
f3096fe30a
|
@ -206,6 +206,8 @@ const zend_function_entry collection_methods[] = {
|
|||
PHP_ME(Collection, sortedByDescending, selector_flags_arginfo, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(Collection, sortedDescending, flags_arginfo, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(Collection, sortedWith, comparator_arginfo, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(Collection, sum, NULL, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(Collection, sumBy, selector_arginfo, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(Collection, take, n_arginfo, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(Collection, takeLast, n_arginfo, ZEND_ACC_PUBLIC)
|
||||
PHP_ME(Collection, takeLastWhile, predicate_arginfo, ZEND_ACC_PUBLIC)
|
||||
|
|
|
@ -2702,6 +2702,71 @@ PHP_METHOD(Collection, sortedWith)
|
|||
RETVAL_NEW_COLLECTION(sorted_with);
|
||||
}
|
||||
|
||||
PHP_METHOD(Collection, sum)
|
||||
{
|
||||
zend_array* current = COLLECTION_FETCH_CURRENT();
|
||||
zval sum;
|
||||
ZVAL_NULL(&sum);
|
||||
ZEND_HASH_FOREACH_VAL(current, zval* val)
|
||||
if (UNEXPECTED(ZVAL_IS_NULL(&sum))) {
|
||||
if (Z_TYPE_P(val) == IS_LONG) {
|
||||
ZVAL_LONG(&sum, 0);
|
||||
} else if (EXPECTED(Z_TYPE_P(val) == IS_DOUBLE)) {
|
||||
ZVAL_DOUBLE(&sum, 0.0);
|
||||
} else {
|
||||
ERR_NOT_NUMERIC();
|
||||
RETURN_NULL();
|
||||
}
|
||||
}
|
||||
if (Z_TYPE_P(val) == IS_LONG) {
|
||||
Z_LVAL(sum) += Z_LVAL_P(val);
|
||||
} else if (EXPECTED(Z_TYPE_P(val) == IS_DOUBLE)) {
|
||||
Z_DVAL(sum) += Z_DVAL_P(val);
|
||||
} else {
|
||||
ERR_NOT_NUMERIC();
|
||||
RETURN_NULL();
|
||||
}
|
||||
ZEND_HASH_FOREACH_END();
|
||||
RETVAL_ZVAL(&sum, 0, 0);
|
||||
}
|
||||
|
||||
PHP_METHOD(Collection, sumBy)
|
||||
{
|
||||
zend_fcall_info fci;
|
||||
zend_fcall_info_cache fcc;
|
||||
ZEND_PARSE_PARAMETERS_START(1, 1)
|
||||
Z_PARAM_FUNC(fci, fcc)
|
||||
ZEND_PARSE_PARAMETERS_END();
|
||||
zend_array* current = COLLECTION_FETCH_CURRENT();
|
||||
zval sum;
|
||||
ZVAL_NULL(&sum);
|
||||
INIT_FCI(&fci, 2);
|
||||
ZEND_HASH_FOREACH_BUCKET(current, Bucket* bucket)
|
||||
CALLBACK_KEYVAL_INVOKE(params, bucket);
|
||||
if (UNEXPECTED(ZVAL_IS_NULL(&sum))) {
|
||||
if (Z_TYPE(retval) == IS_LONG) {
|
||||
ZVAL_LONG(&sum, 0);
|
||||
} else if (EXPECTED(Z_TYPE(retval) == IS_DOUBLE)) {
|
||||
ZVAL_DOUBLE(&sum, 0.0);
|
||||
} else {
|
||||
ERR_NOT_NUMERIC();
|
||||
zval_ptr_dtor(&retval);
|
||||
RETURN_NULL();
|
||||
}
|
||||
}
|
||||
if (Z_TYPE(retval) == IS_LONG) {
|
||||
Z_LVAL(sum) += Z_LVAL(retval);
|
||||
} else if (EXPECTED(Z_TYPE(retval) == IS_DOUBLE)) {
|
||||
Z_DVAL(sum) += Z_DVAL(retval);
|
||||
} else {
|
||||
ERR_NOT_NUMERIC();
|
||||
zval_ptr_dtor(&retval);
|
||||
RETURN_NULL();
|
||||
}
|
||||
ZEND_HASH_FOREACH_END();
|
||||
RETVAL_ZVAL(&sum, 0, 0);
|
||||
}
|
||||
|
||||
PHP_METHOD(Collection, take)
|
||||
{
|
||||
zend_long n;
|
||||
|
|
|
@ -94,6 +94,8 @@ PHP_METHOD(Collection, sortedBy);
|
|||
PHP_METHOD(Collection, sortedByDescending);
|
||||
PHP_METHOD(Collection, sortedDescending);
|
||||
PHP_METHOD(Collection, sortedWith);
|
||||
PHP_METHOD(Collection, sum);
|
||||
PHP_METHOD(Collection, sumBy);
|
||||
PHP_METHOD(Collection, take);
|
||||
PHP_METHOD(Collection, takeLast);
|
||||
PHP_METHOD(Collection, takeLastWhile);
|
||||
|
|
|
@ -807,6 +807,27 @@ class Collection implements ArrayAccess, Countable
|
|||
*/
|
||||
function sortedWith($comparator) {}
|
||||
|
||||
/**
|
||||
* Returns the sum of all elements in the collection.
|
||||
*
|
||||
* All elements should be of the same type, int or double. Otherwise result is undefined.
|
||||
*
|
||||
* @return int|double|null
|
||||
*/
|
||||
function sum() {}
|
||||
|
||||
/**
|
||||
* Returns the sum of all values produced by selector function applied to each element
|
||||
* in the collection.
|
||||
*
|
||||
* All return values of the selector function should be of the same type, int or double.
|
||||
* Otherwise result is undefined.
|
||||
*
|
||||
* @param callable $selector ($value, $key) -> int|double
|
||||
* @return int|double|null
|
||||
*/
|
||||
function sumBy($selector) {}
|
||||
|
||||
/**
|
||||
* Returns a collection containing first n elements.
|
||||
*
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
--TEST--
|
||||
Test Collection::sum() and Collection::sumBy().
|
||||
--FILE--
|
||||
<?php
|
||||
$array = [];
|
||||
for ($i = 0; $i < 50; ++$i) {
|
||||
$array[] = random_int(1, 50);
|
||||
}
|
||||
$collection = Collection::init($array);
|
||||
$sum = array_sum($array);
|
||||
if ($collection->sum() != $sum) {
|
||||
echo 'Collection::sum() failed.', PHP_EOL;
|
||||
}
|
||||
$array = array_map(function ($value) {
|
||||
return [$value, floatval($value / random_int(3, 7))];
|
||||
}, $array);
|
||||
$collection = Collection::init($array);
|
||||
$sum = array_sum(array_column($array, 1));
|
||||
$sum_by = function ($value) {
|
||||
return $value[1];
|
||||
};
|
||||
if ($collection->sumBy($sum_by) != $sum) {
|
||||
echo 'Collection::sumBy() failed.', PHP_EOL;
|
||||
}
|
||||
?>
|
||||
--EXPECT--
|
Reference in New Issue