[PHP-CVS] cvs: php-src /ext/standard array.c basic_functions.c php_array.h /ext/standard/tests array_replace.phpt
johannesThu Jul 31 20:17:07 2008 UTC Added files: /php-src/ext/standard/tests array_replace.phpt Modified files: /php-src/ext/standard array.c basic_functions.c php_array.h Log: - Add array_replace/array_replace_recursive (Mett Wilmas) http://cvs.php.net/viewvc.cgi/php-src/ext/standard/array.c?r1=1.457&r2=1.458&diff_format=u Index: php-src/ext/standard/array.c diff -u php-src/ext/standard/array.c:1.457 php-src/ext/standard/array.c:1.458 --- php-src/ext/standard/array.c:1.457 Thu Jul 24 03:06:16 2008 +++ php-src/ext/standard/array.cThu Jul 31 20:17:06 2008 @@ -21,7 +21,7 @@ +--+ */ -/* $Id: array.c,v 1.457 2008/07/24 03:06:16 felipe Exp $ */ +/* $Id: array.c,v 1.458 2008/07/31 20:17:06 johannes Exp $ */ #include "php.h" #include "php_ini.h" @@ -2500,10 +2500,75 @@ } /* }}} */ -static void php_array_merge_wrapper(INTERNAL_FUNCTION_PARAMETERS, int recursive) /* {{{ */ +PHPAPI int php_array_replace_recursive(HashTable *dest, HashTable *src TSRMLS_DC) /* {{{ */ +{ + zval **src_entry, **dest_entry; + zstr string_key; + uint string_key_len; + ulong num_key; + HashPosition pos; + + for (zend_hash_internal_pointer_reset_ex(src, &pos); +zend_hash_get_current_data_ex(src, (void **)&src_entry, &pos) == SUCCESS; +zend_hash_move_forward_ex(src, &pos)) { + zend_uchar utype; + + switch (zend_hash_get_current_key_ex(src, &string_key, &string_key_len, &num_key, 0, &pos)) { + case HASH_KEY_IS_STRING: + utype = IS_STRING; + goto ukey; + case HASH_KEY_IS_UNICODE: + utype = IS_UNICODE; +ukey: + if (Z_TYPE_PP(src_entry) != IS_ARRAY || + zend_u_hash_find(dest, utype, string_key, string_key_len, (void **)&dest_entry) == FAILURE || + Z_TYPE_PP(dest_entry) != IS_ARRAY) { + + Z_ADDREF_PP(src_entry); + zend_u_hash_update(dest, utype, string_key, string_key_len, src_entry, sizeof(zval *), NULL); + + continue; + } + break; + + case HASH_KEY_IS_LONG: + if (Z_TYPE_PP(src_entry) != IS_ARRAY || + zend_hash_index_find(dest, num_key, (void **)&dest_entry) == FAILURE || + Z_TYPE_PP(dest_entry) != IS_ARRAY) { + + Z_ADDREF_PP(src_entry); + zend_hash_index_update(dest, num_key, src_entry, sizeof(zval *), NULL); + + continue; + } + break; + } + + if (Z_ARRVAL_PP(src_entry)->nApplyCount > 1 || Z_ARRVAL_PP(dest_entry)->nApplyCount > 1 || (*src_entry == *dest_entry && Z_ISREF_PP(dest_entry) && (Z_REFCOUNT_PP(dest_entry) % 2))) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "recursion detected"); + return 0; + } + SEPARATE_ZVAL(dest_entry); + Z_ARRVAL_PP(dest_entry)->nApplyCount++; + Z_ARRVAL_PP(src_entry)->nApplyCount++; + + if (!php_array_replace_recursive(Z_ARRVAL_PP(dest_entry), Z_ARRVAL_PP(src_entry) TSRMLS_CC)) { + Z_ARRVAL_PP(dest_entry)->nApplyCount--; + Z_ARRVAL_PP(src_entry)->nApplyCount--; + return 0; + } + Z_ARRVAL_PP(dest_entry)->nApplyCount--; + Z_ARRVAL_PP(src_entry)->nApplyCount--; + } + + return 1; +} +/* }}} */ + +static void php_array_merge_or_replace_wrapper(INTERNAL_FUNCTION_PARAMETERS, int recursive, int replace) /* {{{ */ { zval ***args = NULL; - int argc, i, params_ok = 1; + int argc, i, params_ok = 1, init_size = 0; /* Get the argument count and check it */ argc = ZEND_NUM_ARGS(); @@ -2522,6 +2587,12 @@ if (Z_TYPE_PP(args[i]) != IS_ARRAY) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument #%d is not an array", i + 1); params_ok = 0; + } else { + int num = zend_hash_num_elements(Z_ARRVAL_PP(args[i])); + + if (num > init_size) { + init_size = num; + } } } if (params_ok == 0) { @@ -2529,12 +2600,16 @@ return; } - array_init(retur
[PHP-CVS] cvs: php-src /ext/standard array.c basic_functions.c php_array.h /ext/standard/tests/array array_fill_keys.phpt
helly Sat Jul 15 10:10:47 2006 UTC Added files: /php-src/ext/standard/tests/array array_fill_keys.phpt Modified files: /php-src/ext/standard array.c basic_functions.c php_array.h Log: - Add array_fill_keys() (Matt W, php_lists at realplain com) http://cvs.php.net/viewvc.cgi/php-src/ext/standard/array.c?r1=1.362&r2=1.363&diff_format=u Index: php-src/ext/standard/array.c diff -u php-src/ext/standard/array.c:1.362 php-src/ext/standard/array.c:1.363 --- php-src/ext/standard/array.c:1.362 Fri Jul 14 22:41:22 2006 +++ php-src/ext/standard/array.cSat Jul 15 10:10:46 2006 @@ -21,7 +21,7 @@ +--+ */ -/* $Id: array.c,v 1.362 2006/07/14 22:41:22 andrei Exp $ */ +/* $Id: array.c,v 1.363 2006/07/15 10:10:46 helly Exp $ */ #include "php.h" #include "php_ini.h" @@ -1646,6 +1646,58 @@ /* }}} */ +/* {{{ proto array array_fill_keys(array keys, mixed val) + Create an array using the elements of the first parameter as keys each initialized to val */ +PHP_FUNCTION(array_fill_keys) +{ + zval **keys, **val, **entry; + HashPosition pos; + + if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &keys, &val) == FAILURE) { + WRONG_PARAM_COUNT; + } + + if (Z_TYPE_PP(keys) != IS_ARRAY) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "First parameter must be an array"); + RETURN_FALSE; + } + + /* Initialize return array */ + array_init(return_value); + + if (!zend_hash_num_elements(Z_ARRVAL_PP(keys))) { + return; + } + + if (PZVAL_IS_REF(*val)) { + SEPARATE_ZVAL(val); + } + + zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(keys), &pos); + while (zend_hash_get_current_data_ex(Z_ARRVAL_PP(keys), (void **)&entry, &pos) == SUCCESS) { + zval_add_ref(val); + + if (Z_TYPE_PP(entry) == IS_STRING || Z_TYPE_PP(entry) == IS_UNICODE) { + zend_u_symtable_update(Z_ARRVAL_P(return_value), Z_TYPE_PP(entry), Z_UNIVAL_PP(entry), Z_UNILEN_PP(entry) + 1, val, sizeof(zval *), NULL); + } else if (Z_TYPE_PP(entry) == IS_LONG) { + zend_hash_index_update(Z_ARRVAL_P(return_value), Z_LVAL_PP(entry), val, sizeof(zval *), NULL); + } else { + zval tmpkey; + + tmpkey = **entry; + zval_copy_ctor(&tmpkey); + convert_to_string(&tmpkey); + + zend_symtable_update(Z_ARRVAL_P(return_value), Z_STRVAL(tmpkey), Z_STRLEN(tmpkey) + 1, val, sizeof(zval *), NULL); + + zval_dtor(&tmpkey); + } + zend_hash_move_forward_ex(Z_ARRVAL_PP(keys), &pos); + } +} +/* }}} */ + + /* {{{ proto array range(mixed low, mixed high[, int step]) U Create an array containing the range of integers or characters from low to high (inclusive) */ PHP_FUNCTION(range) http://cvs.php.net/viewvc.cgi/php-src/ext/standard/basic_functions.c?r1=1.787&r2=1.788&diff_format=u Index: php-src/ext/standard/basic_functions.c diff -u php-src/ext/standard/basic_functions.c:1.787 php-src/ext/standard/basic_functions.c:1.788 --- php-src/ext/standard/basic_functions.c:1.787Sun Jul 2 00:10:36 2006 +++ php-src/ext/standard/basic_functions.c Sat Jul 15 10:10:46 2006 @@ -17,7 +17,7 @@ +--+ */ -/* $Id: basic_functions.c,v 1.787 2006/07/02 00:10:36 bjori Exp $ */ +/* $Id: basic_functions.c,v 1.788 2006/07/15 10:10:46 helly Exp $ */ #include "php.h" #include "php_streams.h" @@ -380,6 +380,12 @@ ZEND_END_ARG_INFO() static +ZEND_BEGIN_ARG_INFO(arginfo_array_fill_keys, 0) + ZEND_ARG_INFO(0, keys) /* ARRAY_INFO(0, keys, 0) */ + ZEND_ARG_INFO(0, val) +ZEND_END_ARG_INFO() + +static ZEND_BEGIN_ARG_INFO_EX(arginfo_range, 0, 0, 2) ZEND_ARG_INFO(0, low) ZEND_ARG_INFO(0, high) @@ -3708,6 +3714,7 @@ PHP_FE(extract, arginfo_extract) PHP_FE(compact, arginfo_compact) PHP_FE(array_fill, arginfo_array_fill) + PHP_FE(array_fill_keys, arginfo_array_fill_keys) PHP_FE(range, arginfo_range) PHP_FE(array_multisort,
Re: [PHP-CVS] cvs: php-src /ext/standard array.c basic_functions.c php_array.h
I'd share the array_sum() code with array_product() code.. They're identical except for + being * in latter. (I guess you simply copy'pasted it? :) --Jani On Wed, 11 May 2005, Andrey Hristov wrote: andrey Wed May 11 07:43:14 2005 EDT Modified files: /php-src/ext/standardbasic_functions.c php_array.h array.c Log: add function array_product() http://cvs.php.net/diff.php/php-src/ext/standard/basic_functions.c?r1=1.714&r2=1.715&ty=u Index: php-src/ext/standard/basic_functions.c diff -u php-src/ext/standard/basic_functions.c:1.714 php-src/ext/standard/basic_functions.c:1.715 --- php-src/ext/standard/basic_functions.c:1.714Tue May 10 08:50:53 2005 +++ php-src/ext/standard/basic_functions.c Wed May 11 07:43:10 2005 @@ -17,7 +17,7 @@ +--+ */ -/* $Id: basic_functions.c,v 1.714 2005/05/10 12:50:53 andrey Exp $ */ +/* $Id: basic_functions.c,v 1.715 2005/05/11 11:43:10 andrey Exp $ */ #include "php.h" #include "php_streams.h" @@ -813,6 +813,7 @@ PHP_FE(array_diff_uassoc, NULL) PHP_FE(array_udiff_uassoc, NULL) PHP_FE(array_sum, NULL) + PHP_FE(array_product, NULL) PHP_FE(array_filter, NULL) PHP_FE(array_map, NULL) PHP_FE(array_chunk, NULL) http://cvs.php.net/diff.php/php-src/ext/standard/php_array.h?r1=1.48&r2=1.49&ty=u Index: php-src/ext/standard/php_array.h diff -u php-src/ext/standard/php_array.h:1.48 php-src/ext/standard/php_array.h:1.49 --- php-src/ext/standard/php_array.h:1.48 Mon Nov 1 07:09:46 2004 +++ php-src/ext/standard/php_array.hWed May 11 07:43:11 2005 @@ -19,7 +19,7 @@ +--+ */ -/* $Id: php_array.h,v 1.48 2004/11/01 12:09:46 helly Exp $ */ +/* $Id: php_array.h,v 1.49 2005/05/11 11:43:11 andrey Exp $ */ #ifndef PHP_ARRAY_H #define PHP_ARRAY_H @@ -92,6 +92,7 @@ PHP_FUNCTION(array_diff_uassoc); PHP_FUNCTION(array_udiff_uassoc); PHP_FUNCTION(array_sum); +PHP_FUNCTION(array_product); PHP_FUNCTION(array_filter); PHP_FUNCTION(array_map); PHP_FUNCTION(array_key_exists); http://cvs.php.net/diff.php/php-src/ext/standard/array.c?r1=1.298&r2=1.299&ty=u Index: php-src/ext/standard/array.c diff -u php-src/ext/standard/array.c:1.298 php-src/ext/standard/array.c:1.299 --- php-src/ext/standard/array.c:1.298 Mon Apr 25 02:13:57 2005 +++ php-src/ext/standard/array.cWed May 11 07:43:11 2005 @@ -21,7 +21,7 @@ +--+ */ -/* $Id: array.c,v 1.298 2005/04/25 06:13:57 dmitry Exp $ */ +/* $Id: array.c,v 1.299 2005/05/11 11:43:11 andrey Exp $ */ #include "php.h" #include "php_ini.h" @@ -3918,9 +3918,56 @@ Z_DVAL_P(return_value) += Z_DVAL(entry_n); } } +/* }}} */ +/* {{{ proto mixed array_product(array input) + Returns the product of the array entries */ +PHP_FUNCTION(array_product) +{ + zval **input, +**entry, +entry_n; + int argc = ZEND_NUM_ARGS(); + HashPosition pos; + double dval; + + if (argc != 1 || zend_get_parameters_ex(argc, &input) == FAILURE) { + WRONG_PARAM_COUNT; + } + + if (Z_TYPE_PP(input) != IS_ARRAY) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "The argument should be an array"); + return; + } + + ZVAL_LONG(return_value, 0); + + for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(input), &pos); +zend_hash_get_current_data_ex(Z_ARRVAL_PP(input), (void **)&entry, &pos) == SUCCESS; +zend_hash_move_forward_ex(Z_ARRVAL_PP(input), &pos)) { + + if (Z_TYPE_PP(entry) == IS_ARRAY || Z_TYPE_PP(entry) == IS_OBJECT) + continue; + + entry_n = **entry; + zval_copy_ctor(&entry_n); + convert_scalar_to_number(&entry_n TSRMLS_CC); + + if (Z_TYPE(entry_n) == IS_LONG && Z_TYPE_P(return_value) == IS_LONG) { + dval = (double)Z_LVAL_P(return_value) * (double)Z_LVAL(entry_n); + if ( (double)LONG_MIN <= dval && dval <= (double)LONG_MAX ) { + Z_
[PHP-CVS] cvs: php-src /ext/standard array.c basic_functions.c php_array.h
andrey Wed May 11 07:43:14 2005 EDT Modified files: /php-src/ext/standard basic_functions.c php_array.h array.c Log: add function array_product() http://cvs.php.net/diff.php/php-src/ext/standard/basic_functions.c?r1=1.714&r2=1.715&ty=u Index: php-src/ext/standard/basic_functions.c diff -u php-src/ext/standard/basic_functions.c:1.714 php-src/ext/standard/basic_functions.c:1.715 --- php-src/ext/standard/basic_functions.c:1.714Tue May 10 08:50:53 2005 +++ php-src/ext/standard/basic_functions.c Wed May 11 07:43:10 2005 @@ -17,7 +17,7 @@ +--+ */ -/* $Id: basic_functions.c,v 1.714 2005/05/10 12:50:53 andrey Exp $ */ +/* $Id: basic_functions.c,v 1.715 2005/05/11 11:43:10 andrey Exp $ */ #include "php.h" #include "php_streams.h" @@ -813,6 +813,7 @@ PHP_FE(array_diff_uassoc, NULL) PHP_FE(array_udiff_uassoc, NULL) PHP_FE(array_sum, NULL) + PHP_FE(array_product, NULL) PHP_FE(array_filter, NULL) PHP_FE(array_map, NULL) PHP_FE(array_chunk, NULL) http://cvs.php.net/diff.php/php-src/ext/standard/php_array.h?r1=1.48&r2=1.49&ty=u Index: php-src/ext/standard/php_array.h diff -u php-src/ext/standard/php_array.h:1.48 php-src/ext/standard/php_array.h:1.49 --- php-src/ext/standard/php_array.h:1.48 Mon Nov 1 07:09:46 2004 +++ php-src/ext/standard/php_array.hWed May 11 07:43:11 2005 @@ -19,7 +19,7 @@ +--+ */ -/* $Id: php_array.h,v 1.48 2004/11/01 12:09:46 helly Exp $ */ +/* $Id: php_array.h,v 1.49 2005/05/11 11:43:11 andrey Exp $ */ #ifndef PHP_ARRAY_H #define PHP_ARRAY_H @@ -92,6 +92,7 @@ PHP_FUNCTION(array_diff_uassoc); PHP_FUNCTION(array_udiff_uassoc); PHP_FUNCTION(array_sum); +PHP_FUNCTION(array_product); PHP_FUNCTION(array_filter); PHP_FUNCTION(array_map); PHP_FUNCTION(array_key_exists); http://cvs.php.net/diff.php/php-src/ext/standard/array.c?r1=1.298&r2=1.299&ty=u Index: php-src/ext/standard/array.c diff -u php-src/ext/standard/array.c:1.298 php-src/ext/standard/array.c:1.299 --- php-src/ext/standard/array.c:1.298 Mon Apr 25 02:13:57 2005 +++ php-src/ext/standard/array.cWed May 11 07:43:11 2005 @@ -21,7 +21,7 @@ +--+ */ -/* $Id: array.c,v 1.298 2005/04/25 06:13:57 dmitry Exp $ */ +/* $Id: array.c,v 1.299 2005/05/11 11:43:11 andrey Exp $ */ #include "php.h" #include "php_ini.h" @@ -3918,9 +3918,56 @@ Z_DVAL_P(return_value) += Z_DVAL(entry_n); } } +/* }}} */ +/* {{{ proto mixed array_product(array input) + Returns the product of the array entries */ +PHP_FUNCTION(array_product) +{ + zval **input, +**entry, +entry_n; + int argc = ZEND_NUM_ARGS(); + HashPosition pos; + double dval; + + if (argc != 1 || zend_get_parameters_ex(argc, &input) == FAILURE) { + WRONG_PARAM_COUNT; + } + + if (Z_TYPE_PP(input) != IS_ARRAY) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "The argument should be an array"); + return; + } + + ZVAL_LONG(return_value, 0); + + for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(input), &pos); +zend_hash_get_current_data_ex(Z_ARRVAL_PP(input), (void **)&entry, &pos) == SUCCESS; +zend_hash_move_forward_ex(Z_ARRVAL_PP(input), &pos)) { + + if (Z_TYPE_PP(entry) == IS_ARRAY || Z_TYPE_PP(entry) == IS_OBJECT) + continue; + + entry_n = **entry; + zval_copy_ctor(&entry_n); + convert_scalar_to_number(&entry_n TSRMLS_CC); + + if (Z_TYPE(entry_n) == IS_LONG && Z_TYPE_P(return_value) == IS_LONG) { + dval = (double)Z_LVAL_P(return_value) * (double)Z_LVAL(entry_n); + if ( (double)LONG_MIN <= dval && dval <= (double)LONG_MAX ) { + Z_LVAL_P(return_value) *= Z_LVAL(entry_n); + continue; + } + } +
[PHP-CVS] cvs: php-src /ext/standard array.c basic_functions.c php_array.h /ext/standard/tests/array array_intersect_1.phpt
andrey Thu Oct 9 04:10:40 2003 EDT Added files: /php-src/ext/standard/tests/array array_intersect_1.phpt Modified files: /php-src/ext/standard array.c basic_functions.c php_array.h Log: New array functions for doing intersection of arrays that are complementary to array_*diff* family of functions. Namely array_uintersect(), array_uintersect_assoc(), array_intersect_uassoc() and array_uintersect_uassoc(). Test case is also included. #docs and news entry later. Index: php-src/ext/standard/array.c diff -u php-src/ext/standard/array.c:1.253 php-src/ext/standard/array.c:1.254 --- php-src/ext/standard/array.c:1.253 Sun Oct 5 15:37:02 2003 +++ php-src/ext/standard/array.cThu Oct 9 04:10:37 2003 @@ -21,7 +21,7 @@ +--+ */ -/* $Id: array.c,v 1.253 2003/10/05 19:37:02 iliaa Exp $ */ +/* $Id: array.c,v 1.254 2003/10/09 08:10:37 andrey Exp $ */ #include "php.h" #include "php_ini.h" @@ -84,6 +84,10 @@ #define INTERSECT_NORMAL 0 #define INTERSECT_ASSOC1 +#define INTERSECT_COMP_DATA_INTERNAL 0 +#define INTERSECT_COMP_DATA_USER 1 +#define INTERSECT_COMP_KEY_INTERNAL 0 +#define INTERSECT_COMP_KEY_USER 1 #define DOUBLE_DRIFT_FIX 0.001 @@ -2712,47 +2716,177 @@ } /* }}} */ -static void php_array_intersect(INTERNAL_FUNCTION_PARAMETERS, int behavior) +static void php_array_intersect(INTERNAL_FUNCTION_PARAMETERS, int behavior, int data_compare_type, int key_compare_type) { zval ***args = NULL; HashTable *hash; - int argc, i, c = 0; + int argc, arr_argc, i, c = 0; Bucket ***lists, **list, ***ptrs, *p; + + char *callback_name; + zval **old_compare_func; + + int (*intersect_key_compare_func)(const void *, const void * TSRMLS_DC); + int (*intersect_data_compare_func)(const void *, const void * TSRMLS_DC); - /* Get the argument count and check it */ + /* Get the argument count */ argc = ZEND_NUM_ARGS(); - if (argc < 2) { - WRONG_PARAM_COUNT; - } /* Allocate arguments array and get the arguments, checking for errors. */ args = (zval ***)safe_emalloc(argc, sizeof(zval **), 0); if (zend_get_parameters_array_ex(argc, args) == FAILURE) { efree(args); WRONG_PARAM_COUNT; } + + old_compare_func = BG(user_compare_func_name); + + if (behavior == INTERSECT_NORMAL) { + intersect_key_compare_func = array_key_compare; + if (data_compare_type == INTERSECT_COMP_DATA_INTERNAL) { + /* array_intersect() */ + + if (argc < 2) { + efree(args); + WRONG_PARAM_COUNT; + } + arr_argc = argc; + intersect_data_compare_func = array_data_compare; + } else if (data_compare_type == INTERSECT_COMP_DATA_USER) { + /* array_uintersect() */ + if (argc < 3) { + efree(args); + WRONG_PARAM_COUNT; + } + arr_argc = argc - 1; + intersect_data_compare_func = array_user_compare; + if (!zend_is_callable(*args[arr_argc], 0, &callback_name)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Not a valid callback %s", callback_name); + efree(callback_name); + efree(args); + return; + } + efree(callback_name); + + BG(user_compare_func_name) = args[arr_argc]; + } else { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "data_compare_type is %d. This should never happen. Please report as a bug", data_compare_type); + return; + } + } else if (behavior == INTERSECT_ASSOC) { + intersect_key_compare_func = array_key_compare; + if (data_compare_type == INTERSECT_COMP_DATA_INTERNAL + && + key_compare_type == INTERSECT_COMP_KEY_INTERNAL) { + /* array_intersect_assoc() */ + + if (argc < 2) { + efree(args); + WRONG_PARAM_COUNT; + } + arr_argc = argc; + intersect_key_compare_func = array_key_compare; + intersect_data_compare_func = array_data_compare; + } else if (data_c
Re: [PHP-CVS] cvs: php-src /ext/standard array.c basic_functions.c php_array.h
I will work on the documentation next week and will add a news entry soon. Andrey Jani Taskinen wrote: Still waiting for the documentation for these..and also where are the NEWS entries? --Jani On Tue, 23 Sep 2003, Andrey Hristov wrote: andrey Tue Sep 23 13:37:29 2003 EDT Modified files: /php-src/ext/standard array.c basic_functions.c php_array.h Log: 4 new functions : array_udiff() array_udiff_assoc() array_diff_uassoc() array_udiff_uassoc() They work like array_diff() or array_diff_assoc() but callback function(s) can be used to perform the comparisons. For example array_udiff_uassoc() expects 2 callbacks are last 2 parameters one is used to compare the values of the entries in the arrays the second to compare the keys. Class methods are also valid callbacks. Even when the data that should be used in the comparison is private or protected then a static method of a class should be used (this behaviour can be seen in the regression test - 007.phpt). -- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-CVS] cvs: php-src /ext/standard array.c basic_functions.c php_array.h
Still waiting for the documentation for these..and also where are the NEWS entries? --Jani On Tue, 23 Sep 2003, Andrey Hristov wrote: >andrey Tue Sep 23 13:37:29 2003 EDT > > Modified files: >/php-src/ext/standard array.c basic_functions.c php_array.h > Log: > 4 new functions : > array_udiff() > array_udiff_assoc() > array_diff_uassoc() > array_udiff_uassoc() > They work like array_diff() or array_diff_assoc() but callback function(s) > can be used to perform the comparisons. For example array_udiff_uassoc() > expects 2 callbacks are last 2 parameters one is used to compare the values > of the entries in the arrays the second to compare the keys. > Class methods are also valid callbacks. Even when the data that should be > used in the comparison is private or protected then a static method of a > class should be used (this behaviour can be seen in the regression test - > 007.phpt). > > -- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-CVS] cvs: php-src /ext/standard array.c basic_functions.c php_array.h
Wez Furlong wrote: > Should these functions really go into the core? > Perhaps they are better off in an extension (pecl/array_utils ?) > > The names aren't really all that obvious to me either. > > --Wez. Hi Wez, well maybe array_udiff_uassoc() and array_diff_uassoc() are of little need but I added them for completeness to array_udiff() and array_udiff_assoc(). It's easy not to export array_udiff_uassoc() and array_diff_uassoc() and this won't hurt me. However I think that array_udiff() and array_udiff_assoc() are useful. As I stated in my talk to Jani, in 4_3 it is impossible to use array_diff() or array_diff_assoc() on arrays that contain objects. When I started to implement (and implemented) these functions few months ago I had no need of them, I did it for fun. However, month or two ago I faced a case where I needed this functionality but unfortunately it wasn't available so I had to find a way to workaround it. Let me show you a small example : class CPerson { private $priv_member; public $public_member; function CPerson($val) { $this->priv_member = $val; $this->public_member = $val; } static function comp_func_cr($a, $b) { if ($a->priv_member === $b->priv_member) return 0; return ($a->priv_member > $b->priv_member)? 1:-1; } }// class CPerson $a = array( "0.1" => new cr(9), "0.5" => new cr(12), 0 => new cr(23), 1=> new cr(4), 2 => new cr(-15), ); $b = array("0.2" => new cr(9), "0.5" => new cr(22), 0 => new cr( 3), 1=> new cr(4), 2 => new cr(-15), ); ?> In this case $a and $b contain objects. Even more they have private member variables. array_diff() is in no use here since it _cannot_ work with objects well : if I execute array_diff($a, $b) the returned array will contain the elements of $a . So, what to do to make a diff of the two arrays and not to code a function (in PHP) for that by myself? -> Implement core function for that. This functionality goes to 5.0.0 where the object model is better and if core functions can work well with object(s) it will be good and not bad IMO. Using array_udiff() it is easy to diff $a and $b : array_udiff($a, $b, array("cr", "comp_func_cr")); ?> If there are better names for these functions I have nothing against to rename them. I named them this way because of the function usort() that sorts an array by using a callback function. Regards, Andrey P.S. I will appreciate the opinion of Marcus Boerger and Sebastian Bergmann whether these functions are useful or not. However, any other opinions are welcome (this is why i cross-post to internals@) > > ----- Original Message - > From: "Andrey Hristov" <[EMAIL PROTECTED]> > To: <[EMAIL PROTECTED]> > Sent: Tuesday, September 23, 2003 6:37 PM > Subject: [PHP-CVS] cvs: php-src /ext/standard array.c basic_functions.c > php_array.h > > > >>andrey Tue Sep 23 13:37:29 2003 EDT >> >> Modified files: >>/php-src/ext/standard array.c basic_functions.c php_array.h >> Log: >> 4 new functions : >> array_udiff() >> array_udiff_assoc() >> array_diff_uassoc() >> array_udiff_uassoc() >> They work like array_diff() or array_diff_assoc() but callback > > function(s) > >> can be used to perform the comparisons. For example array_udiff_uassoc() >> expects 2 callbacks are last 2 parameters one is used to compare the > > values > >> of the entries in the arrays the second to compare the keys. >> Class methods are also valid callbacks. Even when the data that should > > be > >> used in the comparison is private or protected then a static method of a >> class should be used (this behaviour can be seen in the regression > > test - > >> 007.phpt). > > -- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
Re: [PHP-CVS] cvs: php-src /ext/standard array.c basic_functions.c php_array.h
Should these functions really go into the core? Perhaps they are better off in an extension (pecl/array_utils ?) The names aren't really all that obvious to me either. --Wez. - Original Message - From: "Andrey Hristov" <[EMAIL PROTECTED]> To: <[EMAIL PROTECTED]> Sent: Tuesday, September 23, 2003 6:37 PM Subject: [PHP-CVS] cvs: php-src /ext/standard array.c basic_functions.c php_array.h > andrey Tue Sep 23 13:37:29 2003 EDT > > Modified files: > /php-src/ext/standard array.c basic_functions.c php_array.h > Log: > 4 new functions : > array_udiff() > array_udiff_assoc() > array_diff_uassoc() > array_udiff_uassoc() > They work like array_diff() or array_diff_assoc() but callback function(s) > can be used to perform the comparisons. For example array_udiff_uassoc() > expects 2 callbacks are last 2 parameters one is used to compare the values > of the entries in the arrays the second to compare the keys. > Class methods are also valid callbacks. Even when the data that should be > used in the comparison is private or protected then a static method of a > class should be used (this behaviour can be seen in the regression test - > 007.phpt). -- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php
[PHP-CVS] cvs: php-src /ext/standard array.c basic_functions.c php_array.h
andrey Tue Sep 23 13:37:29 2003 EDT Modified files: /php-src/ext/standard array.c basic_functions.c php_array.h Log: 4 new functions : array_udiff() array_udiff_assoc() array_diff_uassoc() array_udiff_uassoc() They work like array_diff() or array_diff_assoc() but callback function(s) can be used to perform the comparisons. For example array_udiff_uassoc() expects 2 callbacks are last 2 parameters one is used to compare the values of the entries in the arrays the second to compare the keys. Class methods are also valid callbacks. Even when the data that should be used in the comparison is private or protected then a static method of a class should be used (this behaviour can be seen in the regression test - 007.phpt). Index: php-src/ext/standard/array.c diff -u php-src/ext/standard/array.c:1.246 php-src/ext/standard/array.c:1.247 --- php-src/ext/standard/array.c:1.246 Mon Sep 22 19:19:17 2003 +++ php-src/ext/standard/array.cTue Sep 23 13:37:28 2003 @@ -21,7 +21,7 @@ +--+ */ -/* $Id: array.c,v 1.246 2003/09/22 23:19:17 andrey Exp $ */ +/* $Id: array.c,v 1.247 2003/09/23 17:37:28 andrey Exp $ */ #include "php.h" #include "php_ini.h" @@ -77,6 +77,10 @@ #define DIFF_NORMAL0 #define DIFF_ASSOC 1 +#define DIFF_COMP_DATA_INTERNAL 0 +#define DIFF_COMP_DATA_USER 1 +#define DIFF_COMP_KEY_INTERNAL 0 +#define DIFF_COMP_KEY_USER 1 #define INTERSECT_NORMAL 0 #define INTERSECT_ASSOC1 @@ -2866,29 +2870,147 @@ /* }}} */ -static void php_array_diff(INTERNAL_FUNCTION_PARAMETERS, int behavior) +static void php_array_diff(INTERNAL_FUNCTION_PARAMETERS, int behavior, int data_compare_type, int key_compare_type) { zval ***args = NULL; HashTable *hash; - int argc, i, c; + int argc, arr_argc, i, c; Bucket ***lists, **list, ***ptrs, *p; + char *callback_name; + + zval **old_compare_func; + int (*diff_key_compare_func)(const void *, const void * TSRMLS_DC); + int (*diff_data_compare_func)(const void *, const void * TSRMLS_DC); + /* Get the argument count and check it */ argc = ZEND_NUM_ARGS(); - if (argc < 2) { - WRONG_PARAM_COUNT; - } - /* Allocate arguments array and get the arguments, checking for errors. */ args = (zval ***)safe_emalloc(argc, sizeof(zval **), 0); if (zend_get_parameters_array_ex(argc, args) == FAILURE) { efree(args); WRONG_PARAM_COUNT; } + + old_compare_func = BG(user_compare_func_name); + + if (behavior == DIFF_NORMAL) { + diff_key_compare_func = array_key_compare; + if (data_compare_type == DIFF_COMP_DATA_INTERNAL) { + /* array_diff */ + + if (argc < 2) { + efree(args); + WRONG_PARAM_COUNT; + } + arr_argc = argc; + diff_data_compare_func = array_data_compare; + } else if (data_compare_type = DIFF_COMP_DATA_USER) { + /* array_udiff */ + if (argc < 3) { + WRONG_PARAM_COUNT; + } + arr_argc = argc - 1; + diff_data_compare_func = array_user_compare; + if (!zend_is_callable(*args[arr_argc], 0, &callback_name)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Not a valid callback %s", callback_name); + efree(callback_name); + efree(args); + return; + } + efree(callback_name); + + BG(user_compare_func_name) = args[arr_argc]; + } + } else if (behavior == DIFF_ASSOC) { + diff_key_compare_func = array_key_compare; + if (data_compare_type == DIFF_COMP_DATA_INTERNAL + && + key_compare_type == DIFF_COMP_KEY_INTERNAL) { + /* array_diff_assoc() */ + + if (argc < 2) { + efree(args); + WRONG_PARAM_COUNT; + } + arr_argc = argc; + diff_key_compare_func = array_key_compare; + diff_data_compare_func = array_data_compare; + } else if (data_compare_type == DIFF_COMP_DATA_USER + && + key_compare_type == DIFF_COMP_KEY_INTERNAL) { +