ID: 7045
Updated by: rodif_bl
Reported By: [EMAIL PROTECTED]
Status: Open
Bug Type: Arrays related
Operating System: Linux RH 6 and 7
PHP Version: 4.1.0
Assigned To: rodif_bl
New Comment:

here is a patch that fixes the
shuffle and adds ashuffle.

Im pretty new to this list and if someone could tell me 
if i can/should apply this to cvs?


--- ext/standard/array.c.old    Sat Jan 12 04:23:55 2002
+++ ext/standard/array.c        Sat Jan 12 10:03:17 2002
@@ -1415,13 +1415,72 @@
 }
 /* }}} */
 
-
-static int array_data_shuffle(const void *a, const void *b TSRMLS_DC)

+static int php_rand_sort(void *base, size_t nmemb, size_t size, int
(*cmp)(const void *, const void *))
 {
-       return (php_rand(TSRMLS_C) % 2) ? 1 : -1;
+        Bucket *t, **new_order;
+        HashTable *ht;
+        int i, j;
+        ulong num_key;
+        char *string_key;
+
+        int status, *tmp;
+
+        new_order = emalloc(sizeof(Bucket *) * nmemb);
+
+        ALLOC_HASHTABLE(ht);
+        zend_hash_init(ht, 0, NULL, ZVAL_PTR_DTOR, 0);
+
+        for(i = 0;i < nmemb;i++)
+        {
+            zval *z_rand;
+            MAKE_STD_ZVAL(z_rand);
+            ZVAL_LONG(z_rand,rand());
+
+            t = *(((Bucket **)base) + i);
+            if(t->nKeyLength == 0)
+                status = zend_hash_index_update(ht, t->h, &z_rand,
sizeof(zval *), NULL);
+            else
+                status = zend_hash_update(ht, t->arKey, t->nKeyLength,
&z_rand, sizeof(zval *), NULL);
+        }
+
+        set_compare_func(SORT_NUMERIC TSRMLS_CC);
+        zend_hash_sort(ht, qsort, array_data_compare, 0);
+
+        zend_hash_internal_pointer_reset(ht);
+        for(i = 0;i < nmemb;i++)
+        {
+            switch(zend_hash_get_current_key(ht, &string_key,
&num_key, 1))
+            {
+                case HASH_KEY_IS_STRING:
+                    for(j = 0;j < nmemb;j++)
+                    {
+                        t = *(((Bucket **)base) + j);
+                       
if(!strncmp(t->arKey,string_key,t->nKeyLength))
+                        {
+                            new_order[i] = *(((Bucket **)base) + j);
+                            break;
+                        }
+                    }
+                    break;
+                case HASH_KEY_IS_LONG:
+                    for(j = 0;j < nmemb;j++)
+                    {
+                        t = *(((Bucket **)base) + j);
+                        if(t->h == num_key)
+                        {
+                            new_order[i] = *(((Bucket **)base) + j);
+                            break;
+                        }
+                    }
+                    break;
+            }
+            zend_hash_move_forward(ht);
+        }
+        memcpy(base, new_order, size * nmemb);
+        zend_hash_destroy(ht);
+        efree(new_order);
 }
 
-
 /* {{{ proto bool shuffle(array array_arg)
    Randomly shuffle the contents of an array */
 PHP_FUNCTION(shuffle)
@@ -1431,7 +1490,23 @@
        if (zend_parse_parameters(1 TSRMLS_CC, "a", &array) == FAILURE) {
                RETURN_FALSE;
        }
-       if (zend_hash_sort(Z_ARRVAL_PP(&array), (sort_func_t)php_mergesort,
array_data_shuffle, 1 TSRMLS_CC) == FAILURE) {
+       if (zend_hash_sort(Z_ARRVAL_PP(&array), (sort_func_t)php_rand_sort,
NULL, 1 TSRMLS_CC) == FAILURE) {
+               RETURN_FALSE;
+       }
+       RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto bool ashuffle(array array_arg)
+   Randomly shuffle the contents of an array keeping keys intact*/
+PHP_FUNCTION(ashuffle)
+{
+       zval *array;
+
+       if (zend_parse_parameters(1 TSRMLS_CC, "a", &array) == FAILURE) {
+               RETURN_FALSE;
+       }
+       if (zend_hash_sort(Z_ARRVAL_PP(&array), (sort_func_t)php_rand_sort,
NULL, 0 TSRMLS_CC) == FAILURE) {
                RETURN_FALSE;
        }
        RETURN_TRUE;
@@ -2880,7 +2955,7 @@
        }  
 
        if (num_req_val == num_avail) {
-               if (zend_hash_sort(Z_ARRVAL_P(return_value),
(sort_func_t)php_mergesort, array_data_shuffle, 1 TSRMLS_CC) ==
FAILURE) {
+               if (zend_hash_sort(Z_ARRVAL_P(return_value),
(sort_func_t)php_rand_sort, NULL, 1 TSRMLS_CC) == FAILURE) {
                        zval_dtor(return_value);
                        RETURN_FALSE;
                }



--- ext/standard/php_array.h.old    Sat Jan 12 10:11:26 2002
+++ ext/standard/php_array.h    Sat Jan 12 10:11:40 2002
@@ -55,6 +55,7 @@
 PHP_FUNCTION(array_fill);
 PHP_FUNCTION(range);
 PHP_FUNCTION(shuffle);
+PHP_FUNCTION(ashuffle);
 PHP_FUNCTION(array_multisort);
 PHP_FUNCTION(array_push);
 PHP_FUNCTION(array_pop);


--- ext/standard/basic_functions.c.old  Sat Jan 12 10:10:36 2002
+++ ext/standard/basic_functions.c  Sat Jan 12 10:10:54 2002
@@ -748,6 +748,7 @@
    PHP_FE(uasort,                  first_arg_force_ref)
    PHP_FE(uksort,                  first_arg_force_ref)
    PHP_FE(shuffle,                 first_arg_force_ref)
+   PHP_FE(ashuffle,                first_arg_force_ref)
    PHP_FE(array_walk,              first_arg_force_ref)
    PHP_FE(count,                                                      
    NULL)
    PHP_FE(end,                     first_arg_force_ref)



Previous Comments:
------------------------------------------------------------------------

[2001-12-13 23:17:46] [EMAIL PROTECTED]

updated php version and short summary.


------------------------------------------------------------------------

[2001-12-13 16:21:02] [EMAIL PROTECTED]

Still behaves the same on PHP 4.1.0/Linux

------------------------------------------------------------------------

[2001-10-15 09:00:00] [EMAIL PROTECTED]

Any news on this?

Derick

------------------------------------------------------------------------

[2000-10-30 10:07:36] [EMAIL PROTECTED]

This is probably the property of sort algorithm used in shuffle.
Whoever wrote it, please take attention!

------------------------------------------------------------------------

[2000-10-05 18:36:22] [EMAIL PROTECTED]

Shuffle() does NOT behave correctly!!!!

------------------------------------------------------------------------

The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
    http://bugs.php.net/?id=7045


Edit this bug report at http://bugs.php.net/?id=7045&edit=1


-- 
PHP Development Mailing List <http://www.php.net/>
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
To contact the list administrators, e-mail: [EMAIL PROTECTED]

Reply via email to