summaryrefslogtreecommitdiff
path: root/ext/standard/array.c
diff options
context:
space:
mode:
authorAndrei Zmievski <andrei@php.net>2001-03-12 03:06:53 +0000
committerAndrei Zmievski <andrei@php.net>2001-03-12 03:06:53 +0000
commitd73ef1242986f84a7bb9e6fa088f19d4f22b05dc (patch)
tree9c64de3a3ae754aab5226d151403886c5896e4a4 /ext/standard/array.c
parent2d54fb39b957cc0ca973d0cbb5d1869567c2df76 (diff)
downloadphp-git-d73ef1242986f84a7bb9e6fa088f19d4f22b05dc.tar.gz
@- Added array_reduce(), which allows iterative reduction of an array
@ to a single value via a callback function. (Andrei) - Added array_reduce(), which allows iterative reduction of an array to a single value via a callback function. - Fixed usage of zend_is_callable() in PCRE.
Diffstat (limited to 'ext/standard/array.c')
-rw-r--r--ext/standard/array.c60
1 files changed, 60 insertions, 0 deletions
diff --git a/ext/standard/array.c b/ext/standard/array.c
index 4538b6bc14..7dcf6b7ebb 100644
--- a/ext/standard/array.c
+++ b/ext/standard/array.c
@@ -2815,6 +2815,66 @@ PHP_FUNCTION(array_sum)
/* }}} */
+/* {{{ proto mixed array_reduce(array input, mixed callback [, int initial])
+ Reduce the array by calling the callback */
+PHP_FUNCTION(array_reduce)
+{
+ zval **input, **callback, **initial;
+ zval **args[2];
+ zval **operand;
+ zval *result = NULL;
+ zval *retval;
+ char *callback_name;
+
+ if (ZEND_NUM_ARGS() < 2 || ZEND_NUM_ARGS() > 3 ||
+ zend_get_parameters_ex(ZEND_NUM_ARGS(), &input, &callback, &initial) == FAILURE) {
+ WRONG_PARAM_COUNT;
+ }
+
+ if (Z_TYPE_PP(input) != IS_ARRAY) {
+ php_error(E_WARNING, "%s() expects argument 1 to be an array",
+ get_active_function_name());
+ return;
+ }
+
+ if (!zend_is_callable(*callback, 0, &callback_name)) {
+ php_error(E_WARNING, "%s() expects argument 2, '%s', to be a valid callback",
+ get_active_function_name(), callback_name);
+ efree(callback_name);
+ return;
+ }
+
+ if (ZEND_NUM_ARGS() > 2)
+ result = *initial;
+
+ if (zend_hash_num_elements(Z_ARRVAL_PP(input)) == 0) {
+ if (result) {
+ *return_value = *result;
+ zval_copy_ctor(return_value);
+ }
+ return;
+ }
+
+ zend_hash_internal_pointer_reset(Z_ARRVAL_PP(input));
+ while (zend_hash_get_current_data(Z_ARRVAL_PP(input), (void **)&operand) == SUCCESS) {
+ if (result) {
+ args[0] = &result;
+ args[1] = operand;
+ if (call_user_function_ex(EG(function_table), NULL, *callback, &retval, 2, args, 0, NULL) == SUCCESS && retval) {
+ result = retval;
+ } else {
+ php_error(E_WARNING, "%s() had an error invoking the reduction callback", get_active_function_name());
+ return;
+ }
+ } else
+ result = *operand;
+
+ zend_hash_move_forward(Z_ARRVAL_PP(input));
+ }
+
+ *return_value = *result;
+}
+
/*
* Local variables:
* tab-width: 4