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