我想随机从 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/