]> granicus.if.org Git - php/commitdiff
@- Added array_reduce(), which allows iterative reduction of an array
authorAndrei Zmievski <andrei@php.net>
Mon, 12 Mar 2001 03:06:53 +0000 (03:06 +0000)
committerAndrei Zmievski <andrei@php.net>
Mon, 12 Mar 2001 03:06:53 +0000 (03:06 +0000)
@  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.

ext/pcre/php_pcre.c
ext/standard/array.c
ext/standard/basic_functions.c
ext/standard/php_array.h

index b65a35600f384312162086b9529b571ef1eeb323..eaba8e6fcf2d1e96b8b8156f82251a8831e5906d 100644 (file)
@@ -726,8 +726,11 @@ char *php_pcre_replace(char *regex,   int regex_len,
 
        /* Verify and use the replacement value. */
        if (use_func) {
-               if (!zend_is_callable(replace_val)) {
-                       php_error(E_WARNING, "Replacement function is invalid or undefined");
+               char *callable_name;
+
+               if (!zend_is_callable(replace_val, 0, &callable_name)) {
+                       php_error(E_WARNING, "Replacement callback '%s' is invalid or undefined", callable_name);
+                       efree(callable_name);
                        result = estrndup(subject, subject_len);
                        *result_len = subject_len;
                        return result;
@@ -1009,7 +1012,7 @@ PHP_FUNCTION(preg_replace)
        if (Z_TYPE_PP(replace) != IS_ARRAY) {
                convert_to_string_ex(replace);
        } else
-               is_callable_replace = zend_is_callable(*replace);
+               is_callable_replace = zend_is_callable(*replace, 1, NULL);
        
        /* if subject is an array */
        if (Z_TYPE_PP(subject) == IS_ARRAY) {
index 4538b6bc1497bd0303feef7e61c661de9b6ba519..7dcf6b7ebbfe395fd9138d2f60bd67ae64e13932 100644 (file)
@@ -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
index 4172a43c4cd1cc2d6896b5c731589a48f666d51c..5c1080c611e00a337590146bfeecdda90f4a39d3 100644 (file)
@@ -573,6 +573,7 @@ function_entry basic_functions[] = {
        PHP_FE(array_values,                                                    NULL)
        PHP_FE(array_count_values,                                              NULL)
        PHP_FE(array_reverse,                                                   NULL)
+       PHP_FE(array_reduce,                                                    NULL)
        PHP_FE(array_pad,                                                               NULL)
        PHP_FE(array_flip,                                                              NULL)
        PHP_FE(array_rand,                                                              NULL)
index 2db8dee4f755baecf53bf07f7a103943d931634f..b38209d6f571cd6b14cd1abce80128e08bd40c42 100644 (file)
@@ -67,6 +67,7 @@ PHP_FUNCTION(array_keys);
 PHP_FUNCTION(array_values);
 PHP_FUNCTION(array_count_values);
 PHP_FUNCTION(array_reverse);
+PHP_FUNCTION(array_reduce);
 PHP_FUNCTION(array_pad);
 PHP_FUNCTION(array_flip);
 PHP_FUNCTION(array_rand);