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, sortedByDescending, selector_flags_arginfo, ZEND_ACC_PUBLIC)
|
||||||
PHP_ME(Collection, sortedDescending, 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, 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, take, n_arginfo, ZEND_ACC_PUBLIC)
|
||||||
PHP_ME(Collection, takeLast, n_arginfo, ZEND_ACC_PUBLIC)
|
PHP_ME(Collection, takeLast, n_arginfo, ZEND_ACC_PUBLIC)
|
||||||
PHP_ME(Collection, takeLastWhile, predicate_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);
|
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)
|
PHP_METHOD(Collection, take)
|
||||||
{
|
{
|
||||||
zend_long n;
|
zend_long n;
|
||||||
|
|
|
@ -94,6 +94,8 @@ PHP_METHOD(Collection, sortedBy);
|
||||||
PHP_METHOD(Collection, sortedByDescending);
|
PHP_METHOD(Collection, sortedByDescending);
|
||||||
PHP_METHOD(Collection, sortedDescending);
|
PHP_METHOD(Collection, sortedDescending);
|
||||||
PHP_METHOD(Collection, sortedWith);
|
PHP_METHOD(Collection, sortedWith);
|
||||||
|
PHP_METHOD(Collection, sum);
|
||||||
|
PHP_METHOD(Collection, sumBy);
|
||||||
PHP_METHOD(Collection, take);
|
PHP_METHOD(Collection, take);
|
||||||
PHP_METHOD(Collection, takeLast);
|
PHP_METHOD(Collection, takeLast);
|
||||||
PHP_METHOD(Collection, takeLastWhile);
|
PHP_METHOD(Collection, takeLastWhile);
|
||||||
|
|
|
@ -807,6 +807,27 @@ class Collection implements ArrayAccess, Countable
|
||||||
*/
|
*/
|
||||||
function sortedWith($comparator) {}
|
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.
|
* 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