Hi,
the attached unified diffs can be used to add new function named 
array_diff_assoc(). This function works like array_diff() (and shares most of 
it code) but it is more restrictive. An element from the result array is 
removed if there is an element in arrays from 2 to N that has same value and 
same key.
PHP script for testing is also attached.

Regards,
Andrey

P.S.
Note that basic_functions.c in the CVS is newer than mine.
--- ../../../php4-200209030900/ext/standard/array.c	Sat Aug 24 04:35:58 2002
+++ array.c	Wed Sep  4 00:38:16 2002
@@ -2588,9 +2588,7 @@
 }
 /* }}} */
 
-/* {{{ proto array array_diff(array arr1, array arr2 [, array ...])
-   Returns the entries of arr1 that have values which are not present in any of the others arguments */
-PHP_FUNCTION(array_diff)
+static void php_array_diff(INTERNAL_FUNCTION_PARAMETERS, int behavior TSRMLS_DC )
 {
 	zval ***args = NULL;
 	HashTable *hash;
@@ -2614,20 +2612,23 @@
 	set_compare_func(SORT_STRING TSRMLS_CC);
 	for (i=0; i<argc; i++) {
 		if (Z_TYPE_PP(args[i]) != IS_ARRAY) {
-			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Argument #%d is not an array", i+1);
+			php_error(E_WARNING, "Argument #%d to array_diff() is not an array", i+1);
 			argc = i; /* only free up to i-1 */
 			goto out;
 		}
 		hash = HASH_OF(*args[i]);
 		list = (Bucket **) pemalloc((hash->nNumOfElements + 1) * sizeof(Bucket *), hash->persistent);
 		if (!list)
-				RETURN_FALSE;
+		        RETURN_FALSE;
 		lists[i] = list;
 		ptrs[i] = list;
 		for (p = hash->pListHead; p; p = p->pListNext)
-				*list++ = p;
+		        *list++ = p;
 		*list = NULL;
-		zend_qsort((void *) lists[i], hash->nNumOfElements, sizeof(Bucket *), array_data_compare TSRMLS_CC);
+		if (behavior == 1)
+			zend_qsort((void *) lists[i], hash->nNumOfElements, sizeof(Bucket *), array_key_compare TSRMLS_CC);
+		else
+			zend_qsort((void *) lists[i], hash->nNumOfElements, sizeof(Bucket *), array_data_compare TSRMLS_CC);
 	}
 
 	/* copy the argument array */
@@ -2635,16 +2636,29 @@
 	zval_copy_ctor(return_value);
 
 	/* go through the lists and look for values of ptr[0]
-		   that are not in the others */
+           that are not in the others */
 	while (*ptrs[0]) {
 		c = 1;
 		for (i=1; i<argc; i++) {
-			while (*ptrs[i] && (0 < (c = array_data_compare(ptrs[0], ptrs[i] TSRMLS_CC))))
-				ptrs[i]++;
-			if (!c) {
-				if (*ptrs[i])
+			if (behavior == 0){
+				while (*ptrs[i] && (0 < (c = array_data_compare(ptrs[0], ptrs[i] TSRMLS_CC))))
+					ptrs[i]++;
+			}else if (behavior == 1){
+				while (*ptrs[i] && (0 < (c = array_key_compare(ptrs[0], ptrs[i] TSRMLS_CC))))
 					ptrs[i]++;
-				break;
+			}
+			if (!c) {
+				if (behavior == 0){
+					if (*ptrs[i])
+						ptrs[i]++;
+					break;
+				}else if (behavior == 1){
+					if (*ptrs[i]){
+						if (array_data_compare(ptrs[0], ptrs[i] TSRMLS_CC) != 0){
+							c = -1;
+						}
+					}
+				}
 			}
 		}
 		if (!c) {
@@ -2658,8 +2672,13 @@
 					zend_hash_index_del(Z_ARRVAL_P(return_value), p->h);  
 				if (!*++ptrs[0])
 					goto out;
-				if (array_data_compare(ptrs[0]-1, ptrs[0] TSRMLS_CC))
-					break;
+				if (behavior == 0){
+					if (array_data_compare(ptrs[0]-1, ptrs[0] TSRMLS_CC))
+						break;
+				}else{
+					if (array_key_compare(ptrs[0]-1, ptrs[0] TSRMLS_CC)) /* always ==1 */
+						break;
+				}
 			}
 		} else {
 			/* ptrs[0] in none of the other arguments */
@@ -2667,22 +2686,45 @@
 			for (;;) {
 				if (!*++ptrs[0])
 					goto out;
-				if (array_data_compare(ptrs[0]-1, ptrs[0] TSRMLS_CC))
-					break;
+				if (behavior == 0){
+					if (array_data_compare(ptrs[0]-1, ptrs[0] TSRMLS_CC))
+						break;
+				}else{
+					if (array_key_compare(ptrs[0]-1, ptrs[0] TSRMLS_CC)) /* always ==1 */
+						break;
+				}
 			}
 		}
 	}
 out:
 	for (i=0; i<argc; i++) {
-			hash = HASH_OF(*args[i]);
+	        hash = HASH_OF(*args[i]);
 		pefree(lists[i], hash->persistent);
 	}
 	efree(ptrs);
 	efree(lists);
 	efree(args);
 }
+
+
+/* {{{ proto array array_diff(array arr1, array arr2 [, array ...])
+   Returns the entries of arr1 that have values which are not present in any of the others arguments */
+PHP_FUNCTION(array_diff)
+{
+	php_array_diff(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0 TSRMLS_CC);
+}
 /* }}} */
 
+
+/* {{{ proto array array_diff_assoc(array arr1, array arr2 [, array ...])
+   Returns the entries of arr1 that have values which are not present in any of the others arguments */
+PHP_FUNCTION(array_diff_assoc)
+{
+	php_array_diff(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1 TSRMLS_CC);
+}
+/* }}} */
+
+
 #define MULTISORT_ORDER	0
 #define MULTISORT_TYPE	1
 #define MULTISORT_LAST	2
@@ -3420,3 +3462,4 @@
  * vim600: noet sw=4 ts=4 fdm=marker
  * vim<600: noet sw=4 ts=4
  */
+
--- ../../../php4-200209030900/ext/standard/php_array.h	Mon May 13 20:36:10 2002
+++ php_array.h	Tue Sep  3 07:31:01 2002
@@ -76,6 +76,7 @@
 PHP_FUNCTION(array_unique);
 PHP_FUNCTION(array_intersect);
 PHP_FUNCTION(array_diff);
+PHP_FUNCTION(array_diff_assoc); 
 PHP_FUNCTION(array_sum);
 PHP_FUNCTION(array_filter);
 PHP_FUNCTION(array_map);
--- ../../../php4-200209030900/ext/standard/basic_functions.c	Tue Aug 27 02:41:49 2002
+++ basic_functions.c	Tue Sep  3 07:30:43 2002
@@ -17,7 +17,7 @@
    +----------------------------------------------------------------------+
  */
 
-/* $Id: basic_functions.c,v 1.499 2002/08/26 23:16:51 helly Exp $ */
+/* $Id: basic_functions.c,v 1.498 2002/08/25 18:21:40 helly Exp $ */
 
 #include "php.h"
 #include "php_streams.h"
@@ -785,6 +785,7 @@
 	PHP_FE(array_unique,													NULL)
 	PHP_FE(array_intersect,													NULL)
 	PHP_FE(array_diff,														NULL)
+	PHP_FE(array_diff_assoc,														NULL)
 	PHP_FE(array_sum,														NULL)
 	PHP_FE(array_filter,													NULL)
 	PHP_FE(array_map,														NULL)
@@ -1435,7 +1436,7 @@
 	3 = save to file in 3rd parameter
 */
 
-/* {{{ proto bool error_log(string message [, int message_type [, string destination [, string extra_headers]]])
+/* {{{ proto bool error_log(string message, int message_type [, string destination] [, string extra_headers])
    Send an error message somewhere */
 PHP_FUNCTION(error_log)
 {
@@ -1473,7 +1474,7 @@
 		
 		case 4:
 			if (zend_get_parameters_ex (4, &string, &erropt, &option, &emailhead) == FAILURE) {
-				php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid arguments");
+				php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid arguments in");
 				RETURN_FALSE;
 			}
 			break;
<?php
$a = array(1,"big"=>2,3,6,3,5,3,3,3,3,3,3,3,3,3,3);
$b = array(2,2,3,3,3,3,3,3,3,3,3,3,3,3,3);
$c = array(-1,1);
echo '$a='.var_export($a,TRUE).";\n";
echo '$b='.var_export($b,TRUE).";\n";
echo '$c='.var_export($c,TRUE).";\n";
var_dump(array_diff($a,$b,$c));
var_dump(array_diff_assoc($a,$b,$c));
?>
-- 
PHP Development Mailing List <http://www.php.net/>
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to