cvs: php4 /ext/standard array.c basic_functions.c php_array.h

From: Date: Mon, 19 Mar 2001 21:20:03 +0000
Subject: cvs: php4 /ext/standard array.c basic_functions.c php_array.h
Groups: php.cvs 
Request: Send a blank email to php-cvs+get-4672@lists.php.net to get a copy of this message
andrei Mon Mar 19 13:20:03 2001 EDT Modified files: /php4/ext/standard array.c basic_functions.c php_array.h Log: @- Added array_map() function that applies a callback to the elements @ of given arrays and returns the result. It can also be used with a @ null callback to transpose arrays. (Andrei) Index: php4/ext/standard/array.c diff -u php4/ext/standard/array.c:1.105 php4/ext/standard/array.c:1.106 --- php4/ext/standard/array.c:1.105 Fri Mar 16 12:46:33 2001 +++ php4/ext/standard/array.c Mon Mar 19 13:20:02 2001 @@ -21,7 +21,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: array.c,v 1.105 2001/03/16 20:46:33 andrei Exp $ */ +/* $Id: array.c,v 1.106 2001/03/19 21:20:02 andrei Exp $ */ #include "php.h" #include "php_ini.h" @@ -2941,7 +2941,7 @@ } else zval_ptr_dtor(&retval); } else { - php_error(E_WARNING, "%s() had an error invoking the reduction callback", get_active_function_name()); + php_error(E_WARNING, "%s() had an error invoking the filter callback", get_active_function_name()); return; } } else if (!zend_is_true(*operand)) @@ -2960,6 +2960,117 @@ break; } } +} +/* }}} */ + + +/* {{{ proto array array_map(mixed callback, array input1 [, array input2 ,...]) + Applies the callback to the elements in given arrays. */ +PHP_FUNCTION(array_map) +{ + zval ***args = NULL; + zval ***params; + zval *callback; + zval *result, *null; + char *callback_name; + int i, k, maxlen = 0; + int *array_len; + + if (ZEND_NUM_ARGS() < 2) { + WRONG_PARAM_COUNT; + } + + args = (zval ***)emalloc(ZEND_NUM_ARGS() * sizeof(zval **)); + if (zend_get_parameters_array_ex(ZEND_NUM_ARGS(), args) == FAILURE) { + efree(args); + WRONG_PARAM_COUNT; + } + + callback = *args[0]; + if (Z_TYPE_P(callback) != IS_NULL && !zend_is_callable(callback, 0, &callback_name)) { + php_error(E_WARNING, "%s() expects argument 1, '%s', to be either NULL or a valid callback", + get_active_function_name(), callback_name); + efree(callback_name); + efree(args); + return; + } + + /* Cache array sizes. */ + array_len = (int*)emalloc((ZEND_NUM_ARGS()-1) * sizeof(int)); + + /* Check that arrays are indeed arrays and calculate maximum size. */ + for (i = 0; i < ZEND_NUM_ARGS()-1; i++) { + if (Z_TYPE_PP(args[i+1]) != IS_ARRAY) { + php_error(E_WARNING, "%s() expects argument %d to be an array", + get_active_function_name(), i + 2); + efree(array_len); + efree(args); + return; + } + array_len[i] = zend_hash_num_elements(Z_ARRVAL_PP(args[i+1])); + if (array_len[i] > maxlen) + maxlen = array_len[i]; + } + + /* Short-circuit: if no callback and only one array, just return it. */ + if (Z_TYPE_P(callback) == IS_NULL && ZEND_NUM_ARGS() == 2) { + *return_value = **args[1]; + zval_copy_ctor(return_value); + efree(array_len); + efree(args); + return; + } + + array_init(return_value); + params = (zval ***)emalloc((ZEND_NUM_ARGS()-1) * sizeof(zval **)); + MAKE_STD_ZVAL(null); + ZVAL_NULL(null); + + /* We iterate through all the arrays at once. */ + for (k = 0; k < maxlen; k++) { + /* + * If no callback, the result will be an array, consisting of current + * entries from all arrays. + */ + if (Z_TYPE_P(callback) == IS_NULL) { + MAKE_STD_ZVAL(result); + array_init(result); + } + + for (i = 0; i < ZEND_NUM_ARGS()-1; i++) { + /* + * If this array still hash elements, add the current one to the + * parameter list, otherwise use null value. + */ + if (k < array_len[i]) { + zend_hash_index_find(Z_ARRVAL_PP(args[i+1]), k, (void **)&params[i]); + } else { + if (Z_TYPE_P(callback) == IS_NULL) + zval_add_ref(&null); + params[i] = &null; + } + + if (Z_TYPE_P(callback) == IS_NULL) + add_next_index_zval(result, *params[i]); + } + + if (Z_TYPE_P(callback) != IS_NULL) { + if (!call_user_function_ex(EG(function_table), NULL, callback, &result, ZEND_NUM_ARGS()-1, params, 0, NULL) == SUCCESS && result) { + php_error(E_WARNING, "%s() had an error invoking the map callback", get_active_function_name()); + efree(array_len); + efree(args); + zval_dtor(return_value); + RETURN_NULL(); + } + } + + add_next_index_zval(return_value, result); + } + + zval_ptr_dtor(&null); + efree(params); + efree(array_len); + efree(args); } /* }}} */ Index: php4/ext/standard/basic_functions.c diff -u php4/ext/standard/basic_functions.c:1.317 php4/ext/standard/basic_functions.c:1.318 --- php4/ext/standard/basic_functions.c:1.317 Fri Mar 16 12:46:33 2001 +++ php4/ext/standard/basic_functions.c Mon Mar 19 13:20:02 2001 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: basic_functions.c,v 1.317 2001/03/16 20:46:33 andrei Exp $ */ +/* $Id: basic_functions.c,v 1.318 2001/03/19 21:20:02 andrei Exp $ */ #include "php.h" #include "php_main.h" @@ -582,6 +582,7 @@ PHP_FE(array_diff, NULL) PHP_FE(array_sum, NULL) PHP_FE(array_filter, NULL) + PHP_FE(array_map, NULL) /* aliases from array.c */ PHP_FALIAS(pos, current, first_arg_force_ref) Index: php4/ext/standard/php_array.h diff -u php4/ext/standard/php_array.h:1.23 php4/ext/standard/php_array.h:1.24 --- php4/ext/standard/php_array.h:1.23 Fri Mar 16 12:46:33 2001 +++ php4/ext/standard/php_array.h Mon Mar 19 13:20:02 2001 @@ -19,7 +19,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_array.h,v 1.23 2001/03/16 20:46:33 andrei Exp $ */ +/* $Id: php_array.h,v 1.24 2001/03/19 21:20:02 andrei Exp $ */ #ifndef PHP_ARRAY_H #define PHP_ARRAY_H @@ -76,6 +76,7 @@ PHP_FUNCTION(array_diff); PHP_FUNCTION(array_sum); PHP_FUNCTION(array_filter); +PHP_FUNCTION(array_map); HashTable* php_splice(HashTable *, int, int, zval ***, int, HashTable **); PHPAPI void php_array_merge(HashTable *dest, HashTable *src, int recursive);

« previous php.cvs (#4672) next »