从PHP数组中获取随机值,但要使其唯一

时间:2011-06-24 17:25:42

标签: php arrays random

我想从数组中选择一个随机值,但要尽可能保持它的唯一性。

例如,如果我从4个元素的数组中选择一个值4次,则所选值应该是随机的,但每次都不同。

如果我从4个元素的相同数组中选择它10次,那么显然会复制一些值。

我现在有这个,但是我仍然会得到重复的值,即使循环运行了4次:

$arr = $arr_history = ('abc', 'def', 'xyz', 'qqq');

for($i = 1; $i < 5; $i++){
  if(empty($arr_history)) $arr_history = $arr; 
  $selected = $arr_history[array_rand($arr_history, 1)];  
  unset($arr_history[$selected]); 
  // do something with $selected here...
}

9 个答案:

答案 0 :(得分:9)

你几乎是对的。问题是unset($arr_history[$selected]);行。 $selected的值不是键,但实际上是一个值,因此未设置将不起作用。

保持与你在那里的相同:

<?php

$arr = $arr_history = array('abc', 'def', 'xyz', 'qqq');

for ( $i = 1; $i < 10; $i++ )
{
  // If the history array is empty, re-populate it.
  if ( empty($arr_history) )
    $arr_history = $arr;

  // Select a random key.
  $key = array_rand($arr_history, 1);

  // Save the record in $selected.
  $selected = $arr_history[$key];

  // Remove the key/pair from the array.
  unset($arr_history[$key]);

  // Echo the selected value.
  echo $selected . PHP_EOL;
}

或者只有少数几行的例子:

<?php

$arr = $arr_history = array('abc', 'def', 'xyz', 'qqq');

for ( $i = 1; $i < 10; $i++ )
{
  // If the history array is empty, re-populate it.
  if ( empty($arr_history) )
    $arr_history = $arr;

  // Randomize the array.
  array_rand($arr_history);

  // Select the last value from the array.
  $selected = array_pop($arr_history);

  // Echo the selected value.
  echo $selected . PHP_EOL;
}

答案 1 :(得分:7)

如何对数组进行洗牌,并关闭项目。

pop返回null时,重置数组。

$orig = array(..);
$temp = $orig;
shuffle( $temp );

function getNextValue()
{
  global $orig;
  global $temp;

  $val = array_pop( $temp );

  if (is_null($val))
  {
    $temp = $orig;
    shuffle( $temp );
    $val = getNextValue();
  }
  return $val;
}

当然,你需要更好地封装它,并做更好的检查和其他类似的事情。

答案 2 :(得分:3)

Php有一个名为shuffle的本机函数,您可以使用它来随机排序数组中的元素。那么这个怎么样?

$arr = ('abc', 'def', 'xyz', 'qqq');

$random = shuffle($arr);

foreach($random as $number) {
    echo $number;
}

答案 3 :(得分:3)

http://codepad.org/sBMEsXJ1

<?php

    $array = array('abc', 'def', 'xyz', 'qqq');

    $numRandoms = 3;

    $final = array();

    $count = count($array);

    if ($count >= $numRandoms) {

        while (count($final) < $numRandoms) {

            $random = $array[rand(0, $count - 1)];

            if (!in_array($random, $final)) {

                array_push($final, $random);
            }
        }
    }

    var_dump($final);

?>

答案 4 :(得分:2)

key!= value,请使用:

$index = array_rand($arr_history, 1);
$selected = $arr_history[$index];  
unset($arr_history[$index]); 

答案 5 :(得分:1)

我这样做是为了为用户创建一个随机的8位数密码:

$characters = array(
    "A","B","C","D","E","F","G","H","J","K","L","M",
    "N","P","Q","R","S","T","U","V","W","X","Y","Z",
    "a","b","c","d","e","f","g","h","i","j","k","m",
    "n","p","q","r","s","t","u","v","w","x","y","z",
    "1","2","3","4","5","6","7","8","9");

for( $i=0;$i<=8;++$i ){
    shuffle( $characters );
    $new_pass .= $characters[0];
}

答案 6 :(得分:1)

如果您不关心数组中的特定值,您可以尝试实现线性同余生成器来生成数组中的所有值。

LCG implementation

Wikipedia列出了您可以使用的一些值,以及选择LCG算法值的规则,因为LCG算法是确定性的,保证不会在句点长度之前重复单个值。

使用这个唯一的数字填充数组后,您只需按顺序获取数组1中的数字。

答案 7 :(得分:1)

$isShowCategory = array();
for ($i=0; $i <5 ; $i++) { 
   $myCategory = array_rand($arrTrCategoryApp,1); 
   if (!in_array($myCategory, $isShowCategory)) {
      $isShowCategory[] = $myCategory;

      #do something 

   }
}

答案 8 :(得分:-1)

简单易懂:

$colors = array('blue', 'green', 'orange');
$history = $colors;

function getColor($colors, &$history){
    if(count($history)==0)
        $history = $colors;
    return array_pop( $history );
}

echo getColor($colors, $history);