【问题标题】:Selecting from an Array using a random key使用随机键从数组中选择
【发布时间】:2013-10-04 12:35:02
【问题描述】:

我的问题有点复杂,但我会尽量解释清楚。

假设我有一个数组:

$array(5){
      [1]=>1,
      [2]=>2,
      [3]=>3,
      [4]=>4,
      [5]=>5
   }

而且我有一个随机生成的密钥,假设$rand = 34526147; 密钥的长度始终相同。

现在的问题是:我想从数组中选择键,这些键是随机排序的,但基于我们拥有的键。我的意思是当我给出相同的键时,它总是会返回相同的顺序,但是如果我更改键,它将返回不同的顺序数组。谢谢你。

【问题讨论】:

  • 对不起,我不明白这个问题。你能补充一些例子吗?
  • 您的意思是使用$rand 作为随机数生成器的种子?
  • 我们有一个问答游戏,其中 2 名玩家在网上互相玩。问题顺序是从数据库中随机选择的,但两位玩家的问题顺序必须相同。因此,为两个玩家生成了一个唯一的密钥。当用户端 AJAX 使用特定键调用服务器上的 PHP 文件时,PHP 应该返回随机排序的问题列表,这对于两个玩家来说必须是相同的。谢谢。
  • Van Campen 不是数字生成器,而是数组的顺序生成器。
  • @YervandKhalapyan:如果这不起作用,您可能希望将问题顺序保存为另一个表。 QuestionOrder (id, questionOrderID, questionId, sequence) 或类似的东西。

标签: php arrays random


【解决方案1】:

我的理解是您想要shuffle() 数组,但无论提供什么$rand 值,都要使其保持一致。我也相信 PHP 在shuffle 中使用rand(在幕后),这使得使用srand 成为可能(为提供的密钥提供一致的随机顺序)。所以,话虽如此:

$rand = 34526247;
srand($rand);
shuffle($array);

因为您总是从同一个“密钥”随机播种,所以您应该获得一致(可重复)的随机播放结果。 (至少 brief test 是这样的)

注意:这意味着$rand 必须是一个数值。而且,如果在任何时候都不是,您需要将其转换为一个。

【讨论】:

  • @StephanB:我仍然觉得你可以用srand 覆盖它(当你需要一个随机数时,它只是避免你自己调用它)。例如每个srand(microtime(true)); rand(); 调用都变成简单的rand();
  • 抱歉,我这么快就删除了我的评论,我想在您添加简短测试后再次检查。似乎 PHP 沙箱缓存了输出,当我使用 PHP 5.3 将您的代码复制到我的 devbox 上的 .php 时,它每次都会产生不同的输出。
  • @StephanB:可能......我确实尝试更改值(得到一个新的随机输出)然后用原始键替换键并收到之前的排序。 (虽然他们可能会 MD5 源代码并保存缓存——谁知道呢)。
  • 作为后续,我尝试ideone 更改标准输入值(这不会影响代码库,但我会认为会删除任何缓存)仍然有一个一致的洗牌。 (虽然我本地没有PHP可以测试)
【解决方案2】:

uksort 允许根据键定义自定义排序:

uksort($array,function($a,$b){
    global $rand;
    return strpos(''.$rand, ''.$a) - strpos(''.$rand, ''.$b);
});

请注意,这假设所有键都存在于 $rand 中。

数组状态示例:

Array ( 
    [3] => 3 
    [4] => 4 
    [5] => 5 
    [2] => 2 
    [1] => 1 ) 

【讨论】:

    【解决方案3】:

    除了 id 之外,您还应该为每个问题/行计算一个新值。这个值需要随着每个新键而改变,并且对你的玩家来说看起来足够随机。您可以简单地将 id 与键相乘,然后按最右边的数字排序,如下所示:

    $key = 1243;
    $questions = array(
      195741 => array('foo'),
      168762 => array('bar'),
      984133 => array('baz'),
    );
    
    $newquestions = array();
    foreach ($questions as $id => $row) {
      // calculate a random looking order depending on $key
      $newquestions[$id * $key % 100] = $row;
    }
    ksort($newquestions);
    

    输出:

    Array
    (
        [19] => Array
            (
                [0] => baz
            )
        [63] => Array
            (
                [0] => foo
            )
        [66] => Array
            (
                [0] => bar
            )
    )
    

    编辑:包括实际排序

    【讨论】:

    • +1 用于跳出框框思考(尽管如果我有空闲时间,我可能必须对其进行单元测试以查看它的可靠性(以及可能发生冲突的位置)。现在我只是给你荣誉。;-)
    • 谢谢,一般流程建立后,计算很容易扩展。对于非游戏,我建议使用流式密码或哈希链:按 id 排序,第一项获取位置哈希(id),所有其他项获取哈希(前一个哈希)。为我工作:D
    【解决方案4】:

    我可能是错的,但我读到您的意思是您在询问是否可以更改 Q 的顺序以匹配 rand int 中给出的顺序。

    $questions = array(
    1=>'one',
    2=>'two',
    3=>'three',
    4=>'four',
    5=>'five',
    );
    
    $rand = 34526147;
    $order = array_unique(str_split($rand));
    
    
    foreach($order as $ord){
    if(array_key_exists($ord, $questions)) {
    echo 'Q:  ' . $ord . ' is  ' .$questions[$ord] . PHP_EOL;
    }
    }
    

    给予:

    问:3是3

    问:4是4

    问:5是5

    问:2是2

    问:1 是一

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-07-30
      • 1970-01-01
      • 2018-06-13
      • 2017-04-16
      • 1970-01-01
      • 1970-01-01
      • 2017-09-16
      • 1970-01-01
      相关资源
      最近更新 更多