Php 使用随机键从数组中选择

Php 使用随机键从数组中选择,php,arrays,random,Php,Arrays,Random,我的问题有点复杂,但我会尽力解释清楚 我有一个数组,比如说: $array(5){ [1]=>1, [2]=>2, [3]=>3, [4]=>4, [5]=>5 } 我有一个随机生成的密钥,比如说,$rand=34526147键的长度始终相同 现在的问题是:我想从数组中选择密钥,这些密钥是随机排序的,但基于我们拥有的密钥。我的意思是,当我给同一个键时,它总是返回相同的顺序,但如果我更改键,它将返回不

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

我有一个数组,比如说:

$array(5){
      [1]=>1,
      [2]=>2,
      [3]=>3,
      [4]=>4,
      [5]=>5
   }
我有一个随机生成的密钥,比如说,
$rand=34526147键的长度始终相同


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

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 ) 

我的理解是,您希望
shuffle()
数组,但要使它与提供的
$rand
值一致。我还相信PHP在
shuffle
中使用
rand
(幕后),这使得可以使用
srand
(为提供的键提供一致的随机顺序)。因此,尽管如此:

$rand = 34526247;
srand($rand);
shuffle($array);
因为你总是从同一个“关键点”随机播种,所以你应该得到一致的(可重复的)洗牌结果。(至少它有一个)


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

除了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
        )
)

编辑:包括实际排序

我可能错了,但我理解你的意思是,你在问是否可以更改Qs的顺序以匹配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;
}
}
给出:

问:三等于三

问:四等于四

问:五等于五

问:2是2


问题:1是1,对不起,我不明白这个问题。你能添加一些例子吗?你的意思是使用
$rand
作为随机数生成器的种子吗?我们有一个问答游戏,其中两名玩家在网上相互玩。问题的顺序是从数据库中随机选择的,但两位玩家的问题顺序必须相同。因此,将为两个玩家生成一个唯一的密钥。当用户端AJAX使用特定键调用服务器上的PHP文件时,PHP应该返回随机排序的问题列表,这对于两个玩家来说必须是相同的。谢谢。Van Campen不是数字生成器,而是数组的顺序生成器。@YervandKhalapyan:如果这不起作用,您可能希望将问题顺序保存为另一个表
QuestionOrder(id,questionOrderID,questionId,sequence)
或类似的东西。@StephanB:我仍然觉得你可以用
srand
来覆盖它(这样你就不用在需要随机数时自己调用它)。e、 g.每个
srand(微时间(真));兰德()调用变得简单
rand()抱歉,我这么快就删除了我的评论,我想在您添加简短测试后再次检查。PHP沙盒似乎缓存了输出,当我使用PHP5.3将您的代码复制到devbox上的a.PHP时,每次都会产生不同的输出。@StephanB:可能。。我确实尝试过更改值(得到一个新的洗牌输出),然后用原来的密钥替换密钥,并收到以前的命令。(虽然他们可能会MD5源代码并保存缓存——谁知道呢)。作为后续行动,我尝试更改stdin值(这不会影响代码库,但我认为会删除任何缓存),但仍然得到一致的洗牌。(虽然我没有PHP本地测试)@YervandKhalapyan:+1,用于跳出框框思考(尽管如果我有空闲时间,我可能需要对它进行单元测试,看看它有多可靠(以及碰撞可能发生的位置)。现在我只给你一些荣誉。;-)谢谢,在一般流程建立之后,计算可以很容易地扩展。对于非游戏,我建议使用流密码或散列链:按id排序,第一项获得位置散列(id),所有其他项获得散列(上一个散列)。为我工作:D