php - 随机遍历数组而不提取重复值

标签 php jquery mysql arrays sorting

我想随机从 PHP 数组中提取值,在从整个数组中提取所有值之前提取相同的值两次。

换句话说,如果我有数组...

 _____
| foo |
| bar |
| baz |
|_____|

...我想提取一个随机值三次而不是提取相同的值两次,所以我可以...

1st:  foo  foo  bar  bar  baz  baz
2nd:  bar  baz  foo  baz  foo  bar
3rd:  baz  bar  baz  foo  bar  foo

...在我的三个独立拉力上。

现在,我意识到我可以通过简单地从数组中删除选定的项目来做到这一点——如果我只从它中拉出一次。 然而,事实并非如此。我需要数组保持完整,因为我想在循环中提取所有值后再次重复随机提取。

总结:我想以随机顺序从数组中迭代地提取所有值,不重复,直到提取所有项目...然后无限期地重复该过程。


认为我通过将 PHP 数组中的每个选定值插入 MySQL 表,然后检查该表以获取每个后续​​数组拉取(如果拉取值在 MySQL 表中)来完成此操作,我重新运行该函数,直到我得到一个以前从未选择过的值)。

这似乎实现了获取所有值而不重复的目标,但在某些情况下我的输出变得有点古怪。

无论如何,这是我的代码,旨在实现预期的效果。我使用 jQuery (ajax) 每 7 秒调用一个 PHP 函数来获取一个新的数组值,并将该值保存在 MySQL 表中以供将来进行重复检查。提取每个可用值后,我截断表并重新开始。

Javascript (jQuery):

function cycle_facts() {        
    $.ajax({ url: 'lib/functions.php',
             data:    {setfact: 'yes'},
             type:    'post',
             success: function(output) {
                $('#header').html(output);
             }
    });
}

PHP:

function set_fact() {
    global $mysqli;

    $facts = get_facts(); //gets associative array with desired values to be randomly pulled

    /* see if all available values have been pulled, and truncate SQL table if so */
    $rows = $mysqli->query('select * from used_facts;');
    $rows = $rows->num_rows;
    if ($rows == sizeof($facts)) {
        $mysqli->query('truncate table used_facts;');
    }

    $fact = array_rand($facts);

    /* see if selected value has already been pulled in this cycle, and rerun function if so */
    $try = $mysqli->query('select * from used_facts where fact = \'' . $mysqli->real_escape_string($fact) . '\';');
    if ($try->num_rows >= 1) {
        set_fact();
    }
    else {
        $mysqli->query('insert into used_facts (fact) values (\'' . $mysqli->real_escape_string($fact) . '\');'); //insert newly selected value into SQL table for future duplication checking
    }

    echo $fact . '|' . $facts[$fact]; //return selected value to jQuery for display
}

所以我可能可以通过一些调整来使用这种方法,但问题本身让我很感兴趣,想知道是否有 stackoverflow 上的优秀人士使用过的更简单、更直接的方法。

谢谢!

最佳答案

这将以随机顺序为您提供数组的每个元素,而无需重新组织原始数组

foreach (shuffle($arr) as $elem) {
  echo $elem;
}

如果您想提高随机播放的真实随机性,请参阅评论以获取更多详细信息。我特别喜欢Fishes Yates Shuffle但是你可以做一些你喜欢的研究和工具:)


PHP 的 shuffle 将重新排列数组的索引 - 即,它会改变输入数组。

如果您想保留输入数组并对其进行随机复制,我已经花时间实现 Fisher-Yates "inside-out"算法给你。

function pureshuffle (array $xs): array {
  $acc = [];
  for ($i = 0; $i < count($xs); $i++) {
    $j = rand(0, $i);
    if ($j != $i) $acc[$i] = $acc[$j]; 
    $acc[$j] = $xs[$i];
  }
  return $acc;
}

$data = [1,2,3,4,5,6,7];

print_r(pureshuffle($data));
// [2,1,4,6,5,7,3]

print_r($data);
// [1,2,3,4,5,6,7]

或者,您可以使用

对 MySQL 结果进行排序
ORDER BY RAND()

它的性能将取决于很多其他因素,但如果查询足够简单并且结果足够小,那应该不是问题。

如果您希望采用这种方法,请快速进行一些谷歌搜索。您会发现很多关于优化 SQL 中随机排序的信息和技巧。

关于php - 随机遍历数组而不提取重复值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17200180/

相关文章:

mysql - 两次连接同一张表时 Sum 返回错误值

php - MySql 'LIKE' 查询执行缓慢

php - 从 php 中的字符串中删除 @email.com

php - 简单的 PHP 表单验证和验证符号

php - 隐藏div的Javascript代码

javascript - 如何使用嵌入式 javascript 在第 3 方网站上创建弹出窗口?

php - 从 XML 文档中查找特定节点

javascript - 如何使用 jquery 中变量的值手动设置 href

javascript - 使用 jQuery 下拉 ul li

mysql - 如何在 MySQL 中克隆结构?