PHP-从数组中随机选择-允许重复

时间:2018-09-29 12:40:10

标签: php arrays

我想知道是否有正确/容易的方法。 我有一个项目数组,我想从该数组中选择一个金额。 问题来了,因为我希望能够选择比数组中实际更多的项目

我目前有以下

$cardsList = array_rand($this->specials, $amount);

当$ amount大于$ this-> specials中的金额时,这会导致错误

  

警告:array_rand():第二个参数必须在1到数组中元素的数量之间

我知道我可以使用for语句并一次选择1个项目,然后将它们添加到数组中,但是有没有更好/更简便的方法?

for($i = 0; $i<$amount; $i++) {
    $cardsList[] = array_rand($this->specials, 1);
}

4 个答案:

答案 0 :(得分:1)

如果金额大于$ this-> specials,请使用随机数再次创建$ amount

$amount = $amount<=count($this->specials)?$amount: rand(0,count($this->specials));
$cardsList = array_rand($this->specials, $amount);

答案 1 :(得分:0)

您可以编写一个可以满足您期望的函数:

function getRandomArrayValues($arr, $amount){
   $result = array();
   for($i = 0; $i < amount; $i++){
      $result[$i] = array_rand($arr, 1);
   }
  return $result;
}

答案 2 :(得分:0)

@Ceri Turner不幸的是,array_rand()如果$ amount大于源数组计数,则将不接受$ amount。您必须编写自定义函数,而内置函数中没有其他任何函数。

在研究了@fyrye的一些建议之后,我对给定的函数做了一些修改。它也可以比上一个更有效地进行随机化。

您可以查看实时示例https://3v4l.org/tPc7A

<?php

function randomizer($sArray, $target) 
{
    $b = (count($sArray)/2); // Randomize count for better result make it half of the total array count
    $c = floor($target/$b); // Loop Count
    $r = $target-($b*$c); // Rest of the Count
    $cardsList = array();
    if($c > 0){
        /* Now Loop for Full Number */
        for($i=0; $i<$c; $i++){
            $cardsList = array_merge($cardsList,array_rand($sArray, $b));
        }
        if($r >= 1){
            $restArray = array_rand($sArray, $r);
            if(is_array($restArray)){
                $cardsList = array_merge($cardsList,$restArray);
            }else{
                $cardsList[] = $restArray;
            }
        }
    }else{
        $cardsList = array_merge($cardsList,array_rand($sArray, $target));
    }
    return $cardsList;
}

//only 8 values
$sArray = range('A', 'H');

$resultArray = randomizer($sArray, 67);
echo 'Amount 50 -  result: ' . count($resultArray) . \PHP_EOL; 
print_r($resultArray);
?>

答案 3 :(得分:0)

您的方法相当普遍,因为array_rand仅返回提供的数组的随机密钥数组,或者在提供1作为数量时从该数组返回单个随机密钥,因此您将强制使用for循环来检索所需的数量,并在请求非常大的数量时导致性能降低。

array_rand的替代方法是使用shuffle。要解析大于源数组的所需数量,请使用array_merge填充数组,直到达到所需数量。然后使用array_slice将改组后的数组减少到恰好所需的数量。

示例:https://3v4l.org/LDSj4

//create an array of 8 values - for this example
$a = range('A', 'H');

//specify a larger amount of values to retrieve
$amount = 20;
//this only occurs when the array is smaller than the amount
while (count($a) < $amount) {
    //fill the array exponentially with the same values until amount is reached
    $a = array_merge($a, $a);
}
//randomize the array order
shuffle($a);
//reduce the array to the desired amount
$a = array_slice($a, 0, $amount);
var_dump($a);

示例结果(结果如示例链接所示);

array(20) {
  [0]=>
  string(1) "F"
  [1]=>
  string(1) "B"
  [2]=>
  string(1) "E"
  [3]=>
  string(1) "B"
  [4]=>
  string(1) "H"
  [5]=>
  string(1) "A"
  [6]=>
  string(1) "C"
  [7]=>
  string(1) "C"
  [8]=>
  string(1) "C"
  [9]=>
  string(1) "G"
  [10]=>
  string(1) "G"
  [11]=>
  string(1) "H"
  [12]=>
  string(1) "D"
  [13]=>
  string(1) "F"
  [14]=>
  string(1) "A"
  [15]=>
  string(1) "G"
  [16]=>
  string(1) "E"
  [17]=>
  string(1) "C"
  [18]=>
  string(1) "E"
  [19]=>
  string(1) "D"
}