skip to Main Content

I am managing a function that can vary a range_pool of numbers with set decimals between them. I would like to find a solution that ensures that these numbers never repeat (create duplicates) when they are generated at the exit of the function.

    `function random($min, $max, $range_pool) {
    
    $decimals = 4;
    
    $collect_range_pool = array();

    for ($i = 0; $i < $range_pool; $i++)
    {
        
        $random_number = mt_rand() / mt_getrandmax();

        $range = $max - $min;

        $random_decimal = $min + $random_number * $range;

        $random_decimal = round($random_decimal, $decimals);

        $collect_range_pool[] = $random_decimal;
    
    }
    
    return $collect_range_pool;
    
}

$generated = random(4.0008, 4.1008, 20);

foreach ($generated as $number)
{
    
    echo $number . '<br>';
    
}`

I am expecting for the number to never repeat.

3

Answers


  1. use array_unique():

    $generated = array_unique(random(4.0008, 4.1008, 20));
    
    Login or Signup to reply.
  2. A simple way is to check if a value has already been drawn, and ignore it if it has:

    function drawDecimal($min, $max, $decimals)
    {
        $random_number = mt_rand() / mt_getrandmax();
        $range = $max - $min;
        $random_decimal = $min + $random_number * $range;
        return round($random_decimal, $decimals);
    }
    
    function drawDecimals($min, $max, $decimals, $len)
    {
        $values = [];
        while(count($values) < $len)
        {
            $value = drawDecimal($min, $max, $decimals);
            if(!in_array($value, $values))
                $values[] = $value;
        }
        return $values;
    }
    
    var_export(drawDecimals(0.0, 1.0, 1, 11));
    

    Output:

    array (
      0 => 0.7,
      1 => 0.1,
      2 => 0.9,
      3 => 0.2,
      4 => 0.5,
      5 => 1.0,
      6 => 0.8,
      7 => 0.3,
      8 => 0.0,
      9 => 0.4,
      10 => 0.6,
    )
    
    Login or Signup to reply.
  3. If pool size is not going to be huge (i.e. you don’t need to care too much about optimisation), you can go the easy route and use an associative array. The key can be the number itself normalised to the exact number of decimals:

    function random(float $min, float $max, int $range_pool): array
    {
        $decimals = 4;
        $collect_range_pool = [];
        $count = 0;
        while ($count < $range_pool) {
            $random_number = mt_rand() / mt_getrandmax();
            $range = $max - $min;
            $random_decimal = $min + $random_number * $range;
            $random_decimal = round($random_decimal, $decimals);
    
            $key = number_format($random_decimal, $decimals, '.', '');
            if (!array_key_exists($key, $collect_range_pool)) {
                $collect_range_pool[$key] = $random_decimal;
                $count++;
            }
        }
        return array_values($collect_range_pool);
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search