【问题标题】:Most efficient way to order a list by a preset random通过预设随机排序列表的最有效方法
【发布时间】:2010-12-15 02:57:03
【问题描述】:

我有一个在线 PHP 系统,用户可以为他们的朋友投票不同的奖项,但是我发现页面中间和底部的奖项总体上获得的票数较少。我希望它是均匀分布的,所以想出随机排序奖励列表,以使其在每次加载页面时都不同。

然而,这似乎让用户感到困惑,因为他们保存或重新访问所有移动的页面,有没有一种方法可以随机排序列表但为该用户保存此顺序,这意味着每个用户的顺序不同。

投票名单来自数据库,奖项名称是预设的。

你知道怎么做吗?

最后我用了:

  //Shuffle & Organise
    if(is_numeric($pg)) { $start = ($pg*15)-14; $end = $pg*15; $pg = (int) $pg; } else { $start = 1; $end = 15; $pg = (int) 1; }
    if($end>count($vote_name)) { $end = count($vote_name); }
    $vote_boxes = range($start,$end);
    srand($user['id']); 
    shuffle($vote_boxes);

  //Create the voting boxes + js
    foreach($vote_boxes as $row) {
        $content .= vote_form($row);
    }

【问题讨论】:

    标签: php mysql list random


    【解决方案1】:

    如果数据库表不是很大(因为如果您谈论的行数超过几行,这会融化您的数据库)。

    <?PHP
    $ip = $_SERVER['REMOTE_ADDR'];
    $sql = "SELECT * FROM table ORDER BY md5(CONCAT(id,'$ip');";
    $result = db_query($sql);
    ?>
    

    这将散列记录的 id 列(实际上是选择任何列)和客户端的 IP 地址。访问该站点的每个 IP 地址都会得到不同的排序,但只要它们的 IP 不变,它就会保持不变。

    【讨论】:

      【解决方案2】:

      要进行实际的洗牌,请使用 Fisher-Yates 洗牌算法。在随机播放之前使用每个用户独有的东西来播种 prng。

      【讨论】:

        【解决方案3】:

        我想你的用户在 users 表中有唯一的 id,所以为什么不简单

         select * from awards order by rand($user_id)
        

        rand() 可以接受表示“种子”的参数

        【讨论】:

        • 我不知道它接受了种子,一直想知道为什么它有 () 非常有用但不是我这次要找的。​​span>
        • 正是你要找的。​​span>
        【解决方案4】:

        最有效的方法可能是创建一个完全随机的数组顺序并为每个用户缓存。

        除了上面的 MySQL 解决方案 postet,您可以以非常相似的方式使用 php:您可以使用会话 id 作为随机数生成器的开始,然后使用“随机”数对数组进行洗牌。通过这样做,每个用户在请求您的网站时都会收到一个不同排序的列表(至少只要会话没有过期)。

        <?php
        
          $array = array("Cat", "Dog", "Mouse");
        
          session_start();
          $session_id_int = (int)session_id();
          srand($session_id_int);
        
          echo '<pre>BEFORE:'.PHP_EOL;
          print_r($array);
        
          shuffle($array);
        
          echo 'AFTER:'.PHP_EOL;
          print_r($array);
        

        【讨论】:

        • 我使用了一个基于您发布的信息并结合上述 MySQL 解决方案的解决方案。完成后我会在这里发布。
        猜你喜欢
        • 1970-01-01
        • 2010-09-27
        • 2017-12-05
        • 1970-01-01
        • 2022-10-04
        • 1970-01-01
        • 1970-01-01
        • 2012-08-05
        • 2016-11-22
        相关资源
        最近更新 更多