Random Numbers without duplication using an array in PHP

后端 未结 1 1817
忘掉有多难
忘掉有多难 2021-01-28 23:22

I\'m trying to create a random number generator in PHP. It\'s supposed to generate three (3) numbers at a time, without repeat. That\'s to say, the 3 numbers cannot be the same.

相关标签:
1条回答
  • 2021-01-29 00:08

    Like this ( as per my initial comment ),

    $array = [];
    
    while( count($array) < 3 ){
        $rand = mt_rand(1,36);
        $array[$rand] = $rand;
    }
    
    print_r( $array );
    

    By setting the "key" to be the random number, we can abuse the fact that associative array keys are unique. Then it's a simple matter of waiting until the array contains the desired amount of unique items.

    You can test it here

    Outputs: ( your results may vary, it's random )

    Array
    (
        [16] => 16
        [20] => 20
        [27] => 27
    )
    

    UPDATE I was trying to think of a valid way to do it without using a loop ( on my way home from work ), and this way may be even better in some cases.

    $a = range(1,36);
    
    shuffle($a);
    
    $array = array_slice($a, 0, 3);
    
    print_r($array);
    

    This will have better performance when the number of items you must find is higher. This is because there is no repetition, no collisions. So if you have a small range but need to find many items for the return, this will preform better. If you have many items and need to return only few, then the first one may be better, if not from speed then from memory use.

    You can see it here

    For reference this uses

    range() - Create an array containing a range of elements.

    http://php.net/manual/en/function.range.php

    shuffle() - Shuffles (randomizes the order of the elements in) an array. It uses a pseudo random number generator that is not suitable for cryptographic purposes.

    http://php.net/manual/en/function.shuffle.php

    array_slice() - Returns the sequence of elements from the array as specified by the offset and length parameters.

    http://php.net/manual/en/function.array-slice.php

    So to explain this last one

    • First we create an array that contains each of our possible numbers as an element. So for example like this [1,2,3,4,5,6, ...].
    • Next we shuffle it which randomizes the order of the whole array. Shuffle modifies the array by "reference" so it doesn't return our array and therefor there is no assignment ( I think it returns Boolean, however I'm at a loss as to how it could fail and return false, pretty much it just returns true which we don't want to overwrite our array with ). So our example then becomes this [16,20,27,14,5,1, ...]
    • Last we cut out the number of items we need to return. Finally we end the example with this [16,20,27];

    You can crunch the first one down into one ( really 2) line by assigning the value of the $rand variable in the condition of the loop. Like this:

    $array = [];
    
    while( count($array) < 3 && false !== ($rand = mt_rand(1,36))) $array[$rand] = $rand;
    

    Because mt_rand(1,36) will never return boolan false. Also if I remember mt_rand is the same as rand now, or at least in current PHP versions.

    Note: As of PHP 7.1.0, rand() uses the same random number generator as mt_rand(). To preserve backwards compatibility rand() allows max to be smaller than min as opposed to returning FALSE as mt_rand(). http://php.net/manual/en/function.rand.php

    Hope it helps you, remember to think outside of the box.

    0 讨论(0)
提交回复
热议问题