andrey Sat Sep 21 10:50:04 2002 EDT Modified files: /php4/ext/standard array.c php_array.h basic_functions.c Log: New function added - array_intersect_assoc() similar to array_intersect() but the keys are also used in the comparison. So the result is a subset of the result of array_intersect(). Test will be committed too. Index: php4/ext/standard/array.c diff -u php4/ext/standard/array.c:1.192 php4/ext/standard/array.c:1.193 --- php4/ext/standard/array.c:1.192 Thu Sep 12 04:20:37 2002 +++ php4/ext/standard/array.c Sat Sep 21 10:50:03 2002 @@ -21,7 +21,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: array.c,v 1.192 2002/09/12 08:20:37 andrey Exp $ */ +/* $Id: array.c,v 1.193 2002/09/21 14:50:03 andrey Exp $ */ #include "php.h" #include "php_ini.h" @@ -78,6 +78,9 @@ #define DIFF_NORMAL 0 #define DIFF_ASSOC 1 +#define INTERSECT_NORMAL 0 +#define INTERSECT_ASSOC 1 + PHP_MINIT_FUNCTION(array) { #ifdef ZTS @@ -2519,9 +2522,7 @@ } /* }}} */ -/* {{{ proto array array_intersect(array arr1, array arr2 [, array ...]) - Returns the entries of arr1 that have values which are present in all the other arguments */ -PHP_FUNCTION(array_intersect) +static void php_array_intersect(INTERNAL_FUNCTION_PARAMETERS, int behavior) { zval ***args = NULL; HashTable *hash; @@ -2558,7 +2559,11 @@ for (p = hash->pListHead; p; p = p->pListNext) *list++ = p; *list = NULL; - zend_qsort((void *) lists[i], hash->nNumOfElements, sizeof(Bucket *), array_data_compare TSRMLS_CC); + if (behavior == INTERSECT_NORMAL) { + zend_qsort((void *) lists[i], hash->nNumOfElements, +sizeof(Bucket *), array_data_compare TSRMLS_CC); + } else if (behavior == INTERSECT_ASSOC) { + zend_qsort((void *) lists[i], hash->nNumOfElements, +sizeof(Bucket *), array_key_compare TSRMLS_CC); + } } /* copy the argument array */ @@ -2568,11 +2573,26 @@ /* go through the lists and look for common values */ while (*ptrs[0]) { for (i=1; i<argc; i++) { - while (*ptrs[i] && (0 < (c = array_data_compare(ptrs[0], ptrs[i] TSRMLS_CC)))) - ptrs[i]++; + if (behavior == INTERSECT_NORMAL) { + while (*ptrs[i] && (0 < (c = +array_data_compare(ptrs[0], ptrs[i] TSRMLS_CC)))) + ptrs[i]++; + } else if (behavior == INTERSECT_ASSOC) { + while (*ptrs[i] && (0 < (c = +array_key_compare(ptrs[0], ptrs[i] TSRMLS_CC)))) + ptrs[i]++; + if (!c && *ptrs[i]) { /* this means that ptrs[i] is +not NULL so we can compare */ + /* and "c==0" is from last operation */ + if (array_data_compare(ptrs[0], ptrs[i] +TSRMLS_CC) != 0) { + c = 1; + /* we are going to the break */ + } else { + /* continue looping */ + } + } + } if (!*ptrs[i]) { /* delete any values corresponding to remains of ptrs[0] */ - /* and exit */ + /* and exit because they do not present in at least +one of */ + /* the other arguments */ for (;;) { p = *ptrs[0]++; if (!p) @@ -2583,7 +2603,7 @@ zend_hash_index_del(Z_ARRVAL_P(return_value), p->h); } } - if (c) + if (c) /* here we get if not all are equal */ break; ptrs[i]++; } @@ -2598,8 +2618,13 @@ zend_hash_index_del(Z_ARRVAL_P(return_value), p->h); if (!*++ptrs[0]) goto out; - if (0 <= array_data_compare(ptrs[0], ptrs[i] TSRMLS_CC)) + if (behavior == INTERSECT_NORMAL) { + if (0 <= array_data_compare(ptrs[0], ptrs[i] +TSRMLS_CC)) + break; + } else if (behavior == INTERSECT_ASSOC) { + /* no need of looping because indexes are +unique */ break; + } } } else { /* ptrs[0] is present in all the arguments */ @@ -2607,8 +2632,13 @@ for (;;) { if (!*++ptrs[0]) goto out; - if (array_data_compare(ptrs[0]-1, ptrs[0] TSRMLS_CC)) + if (behavior == INTERSECT_NORMAL) { + if (array_data_compare(ptrs[0]-1, ptrs[0] +TSRMLS_CC)) + break; + } else if (behavior == INTERSECT_ASSOC) { + /* no need of looping because indexes are +unique */ break; + } } } } @@ -2622,7 +2652,23 @@ efree(lists); efree(args); } + +/* {{{ proto array array_intersect(array arr1, array arr2 [, array ...]) + Returns the entries of arr1 that have values which are present in all the other +arguments */ +PHP_FUNCTION(array_intersect) +{ + php_array_intersect(INTERNAL_FUNCTION_PARAM_PASSTHRU, INTERSECT_NORMAL); +} /* }}} */ + +/* {{{ proto array array_intersect_assoc(array arr1, array arr2 [, array ...]) + Returns the entries of arr1 that have values which are present in all the other +arguments. Keys are used to do more restrctive check */ +PHP_FUNCTION(array_intersect_assoc) +{ + php_array_intersect(INTERNAL_FUNCTION_PARAM_PASSTHRU, INTERSECT_ASSOC); +} +/* }}} */ + static void php_array_diff(INTERNAL_FUNCTION_PARAMETERS, int behavior) { Index: php4/ext/standard/php_array.h diff -u php4/ext/standard/php_array.h:1.38 php4/ext/standard/php_array.h:1.39 --- php4/ext/standard/php_array.h:1.38 Wed Sep 11 14:13:48 2002 +++ php4/ext/standard/php_array.h Sat Sep 21 10:50:04 2002 @@ -19,7 +19,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_array.h,v 1.38 2002/09/11 18:13:48 andrey Exp $ */ +/* $Id: php_array.h,v 1.39 2002/09/21 14:50:04 andrey Exp $ */ #ifndef PHP_ARRAY_H #define PHP_ARRAY_H @@ -75,6 +75,7 @@ PHP_FUNCTION(array_rand); PHP_FUNCTION(array_unique); PHP_FUNCTION(array_intersect); +PHP_FUNCTION(array_intersect_assoc); PHP_FUNCTION(array_diff); PHP_FUNCTION(array_diff_assoc); PHP_FUNCTION(array_sum); Index: php4/ext/standard/basic_functions.c diff -u php4/ext/standard/basic_functions.c:1.507 php4/ext/standard/basic_functions.c:1.508 --- php4/ext/standard/basic_functions.c:1.507 Thu Sep 19 12:01:53 2002 +++ php4/ext/standard/basic_functions.c Sat Sep 21 10:50:04 2002 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: basic_functions.c,v 1.507 2002/09/19 16:01:53 zeev Exp $ */ +/* $Id: basic_functions.c,v 1.508 2002/09/21 14:50:04 andrey Exp $ */ #include "php.h" #include "php_streams.h" @@ -797,6 +797,7 @@ PHP_FE(array_rand, NULL) PHP_FE(array_unique, NULL) PHP_FE(array_intersect, NULL) + PHP_FE(array_intersect_assoc, + NULL) PHP_FE(array_diff, NULL) PHP_FE(array_diff_assoc, NULL) PHP_FE(array_sum, NULL)
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php