Hi,
pasted in and attached to this mail is patch which gives the opportunity for 
programmer to move the internal pointer of the array when searching with 
array_search(). Fourth parameter (move_pointer) of type bool is added.
Why I did that? Few days ago I was asked by a man on #php how when he finds what he 
wants using array_search to traverse the array forwards and backwards starting from 
the key returned by array_search.
The only way for him to do that was to use integers as keys and additional variable. 
Using this new feature the user will not be limited to integer indeces.

Andrey

The diff follows (it is against /* $Id: array.c,v 1.181 2002/08/03 00:40:46 rodif_bl 
Exp $ */):

--- array.c     Sat Aug  3 03:48:15 2002
+++ ../array.c  Sun Aug  4 16:12:17 2002
@@ -1030,10 +1030,19 @@
  */
 static void php_search_array(INTERNAL_FUNCTION_PARAMETERS, int behavior)
 {
+#define SEARCH_MOVE_POINTER(___move_pointer,___hash,___how) \
+if (___move_pointer){\
+       zend_hash_internal_pointer_reset(___hash);\
+       while ((--___how) >0){\
+               zend_hash_move_forward(___hash);\
+       }\
+}
+       
        zval **value,                           /* value to check for */
                 **array,                               /* array to check in */
                 **strict,                              /* strict comparison or not */
                 **entry,                               /* pointer to array entry */
+                **move_pointer,                /* whether to move internal pointer or 
+not */
                  res;                                  /* comparison result */
        HashTable *target_hash;         /* array hashtable */
        HashPosition pos;                       /* hash iterator */
@@ -1041,9 +1050,11 @@
        uint str_key_len;
        char *string_key;
        int (*is_equal_func)(zval *, zval *, zval * TSRMLS_DC) = is_equal_function;
+       int iterations = 0;
+       int mv_pointer = 0;
                
-       if (ZEND_NUM_ARGS() < 2 || ZEND_NUM_ARGS() > 3 ||
-               zend_get_parameters_ex(ZEND_NUM_ARGS(), &value, &array, &strict) == 
FAILURE) {
+       if (ZEND_NUM_ARGS() < 2 || ZEND_NUM_ARGS() > 4 ||
+               zend_get_parameters_ex(ZEND_NUM_ARGS(), &value, &array, &strict, 
+&move_pointer) == FAILURE) {
                WRONG_PARAM_COUNT;
        }
        
@@ -1057,27 +1068,38 @@
                RETURN_FALSE;
        }
 
-       if (ZEND_NUM_ARGS() == 3) {
+       if (ZEND_NUM_ARGS() >= 3) {
                convert_to_boolean_ex(strict);
                if (Z_LVAL_PP(strict)) {
                        is_equal_func = is_identical_function;
                }
        }
+       
+       if (ZEND_NUM_ARGS() == 4) {
+               convert_to_boolean_ex(move_pointer);
+               if (Z_LVAL_PP(move_pointer)){
+                       mv_pointer = 1;
+               }
+       }
 
        target_hash = HASH_OF(*array);
        zend_hash_internal_pointer_reset_ex(target_hash, &pos);
        while(zend_hash_get_current_data_ex(target_hash, (void **)&entry, &pos) == 
SUCCESS) {
+               iterations++;
                is_equal_func(&res, *value, *entry TSRMLS_CC);
                if (Z_LVAL(res)) {
                        if (behavior==0) {               
+                               SEARCH_MOVE_POINTER(mv_pointer,target_hash, 
+iterations);
                                RETURN_TRUE;
                        } else {
                                /* Return current key */
                                switch (zend_hash_get_current_key_ex(target_hash, 
&string_key, &str_key_len, &num_key, 0,  &pos)) {
                                        case HASH_KEY_IS_STRING:
+                                               SEARCH_MOVE_POINTER(mv_pointer, 
+target_hash, iterations);
                                                RETURN_STRINGL(string_key, 
str_key_len-1, 1);
                                                break;
                                        case HASH_KEY_IS_LONG:
+                                               SEARCH_MOVE_POINTER(mv_pointer, 
+target_hash, iterations);
                                                RETURN_LONG(num_key);
                                                break;
                                }
@@ -1088,6 +1110,7 @@
        }
    
        RETURN_FALSE;
+#undef SEARCH_MOVE_POINTER
 }
 
 
@@ -1099,7 +1122,7 @@
 }
 /* }}} */
 
-/* {{{ proto mixed array_search(mixed needle, array haystack [, bool strict])
+/* {{{ proto mixed array_search(mixed needle, array haystack [, bool strict [, bool 
+move_pointer]])
    Searches the array for a given value and returns the corresponding key if 
successful */
 PHP_FUNCTION(array_search)
 {
--- array.c	Sat Aug  3 03:48:15 2002
+++ ../array.c	Sun Aug  4 16:12:17 2002
@@ -1030,10 +1030,19 @@
  */
 static void php_search_array(INTERNAL_FUNCTION_PARAMETERS, int behavior)
 {
+#define SEARCH_MOVE_POINTER(___move_pointer,___hash,___how) \
+if (___move_pointer){\
+	zend_hash_internal_pointer_reset(___hash);\
+	while ((--___how) >0){\
+		zend_hash_move_forward(___hash);\
+	}\
+}
+	
  	zval **value,				/* value to check for */
 		 **array,				/* array to check in */
 		 **strict,				/* strict comparison or not */
 		 **entry,				/* pointer to array entry */
+		 **move_pointer,		/* whether to move internal pointer or not */
 		  res;					/* comparison result */
 	HashTable *target_hash;		/* array hashtable */
 	HashPosition pos;			/* hash iterator */
@@ -1041,9 +1050,11 @@
 	uint str_key_len;
    	char *string_key;
 	int (*is_equal_func)(zval *, zval *, zval * TSRMLS_DC) = is_equal_function;
+	int iterations = 0;
+	int mv_pointer = 0;
 	  	
-	if (ZEND_NUM_ARGS() < 2 || ZEND_NUM_ARGS() > 3 ||
-		zend_get_parameters_ex(ZEND_NUM_ARGS(), &value, &array, &strict) == FAILURE) {
+	if (ZEND_NUM_ARGS() < 2 || ZEND_NUM_ARGS() > 4 ||
+		zend_get_parameters_ex(ZEND_NUM_ARGS(), &value, &array, &strict, &move_pointer) == FAILURE) {
 		WRONG_PARAM_COUNT;
 	}
 	
@@ -1057,27 +1068,38 @@
 		RETURN_FALSE;
 	}
 
-	if (ZEND_NUM_ARGS() == 3) {
+	if (ZEND_NUM_ARGS() >= 3) {
 		convert_to_boolean_ex(strict);
 		if (Z_LVAL_PP(strict)) {
 			is_equal_func = is_identical_function;
 		}
 	}
+	
+	if (ZEND_NUM_ARGS() == 4) {
+		convert_to_boolean_ex(move_pointer);
+		if (Z_LVAL_PP(move_pointer)){
+			mv_pointer = 1;
+		}
+	}
 
 	target_hash = HASH_OF(*array);
 	zend_hash_internal_pointer_reset_ex(target_hash, &pos);
 	while(zend_hash_get_current_data_ex(target_hash, (void **)&entry, &pos) == SUCCESS) {
+		iterations++;
 	 	is_equal_func(&res, *value, *entry TSRMLS_CC);
 		if (Z_LVAL(res)) {
 			if (behavior==0) {		 
+				SEARCH_MOVE_POINTER(mv_pointer,target_hash, iterations);
 				RETURN_TRUE;
 			} else {
 				/* Return current key */
 				switch (zend_hash_get_current_key_ex(target_hash, &string_key, &str_key_len, &num_key, 0,  &pos)) {
 					case HASH_KEY_IS_STRING:
+						SEARCH_MOVE_POINTER(mv_pointer, target_hash, iterations);
 						RETURN_STRINGL(string_key, str_key_len-1, 1);
 						break;
 					case HASH_KEY_IS_LONG:
+						SEARCH_MOVE_POINTER(mv_pointer, target_hash, iterations);
 						RETURN_LONG(num_key);
 						break;
 				}
@@ -1088,6 +1110,7 @@
 	}
    
 	RETURN_FALSE;
+#undef SEARCH_MOVE_POINTER
 }
 
 
@@ -1099,7 +1122,7 @@
 }
 /* }}} */
 
-/* {{{ proto mixed array_search(mixed needle, array haystack [, bool strict])
+/* {{{ proto mixed array_search(mixed needle, array haystack [, bool strict [, bool move_pointer]])
    Searches the array for a given value and returns the corresponding key if successful */
 PHP_FUNCTION(array_search)
 {
-- 
PHP Development Mailing List <http://www.php.net/>
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to