随机遍历数组,而无需提取重复值 [英] Randomly iterate through array without pulling duplicate values

查看:68
本文介绍了随机遍历数组,而无需提取重复值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想从PHP数组中随机抽取值,将相同的值抽取两次,然后再从整个数组中抽取所有值.

I would like to pull values from a PHP array at random, without pulling the same value twice before I've pulled all values from the entire array.

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

In other words, if I have the array...

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

...我想提取3次随机值而又不提取2次相同值,所以我可以...

...I want to pull a random value three times without pulling the same value twice, so I could have...

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

...在我的三个单独项中.

...on my three separate pulls.

现在,我意识到我可以通过简单地从阵列中删除选定的项目来做到这一点-如果我只从阵列中取出一次.但是,事实并非如此.我需要数组保持完好无缺,因为一旦在一个周期中提取了所有值,我想再次重复随机提取.

Now, I realize I could do this by simply removing the selected item from the array--IF I was only pulling from it once. However, that is not the case. I need the array to stay intact because I want to repeat the random pulls all over again once all values have been pulled in a cycle.

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

To summarize: I want to pull all values iteratively from an array in a random order without duplicates, until all items have been pulled...and then repeat the process indefinitely.

认为通过将PHP数组中的每个选定值插入到MySQL表中,然后检查该表中的每个后续数组拉取(如果拉出的值在MySQL表中),就可以实现此目标,我重新运行该函数,直到获得从未选择的值为止.

I thought I had this accomplished by inserting each selected value from the PHP array into a MySQL table, and then checking that table for each subsequent array pull (if the pulled value was in the MySQL table, I re-ran the function until I got a never-before-selected value).

这似乎实现了不重复获取所有值的目标,但是在某些情况下,我的输出变得有些时髦.

This seems to accomplish the get-all-values-without-duplicates goal, but my output became a little funky in some cases.

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

At any rate, here is my code intended to accomplish the desired effect. I use jQuery (ajax) to call a PHP function every 7 seconds to get a new array value, and stick that value in a MySQL table for future duplication checking. When every available value has been pulled, I truncate the table and start over again.

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上的优秀人员采用.


So I can probably use this approach with some tweaking, but the problem itself intrigued me enough to wonder if there was a simpler, more direct approach that fine folks on stackoverflow have used.

谢谢!

推荐答案

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

This will give you each element of the array in a random order without reorganizing the original array

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

如果您想改善随机播放的真正随机性,请参阅评论以获取更多详细信息.我特别喜欢 Fishes Yates Shuffle ,但是您可以对工具进行一些研究任何你喜欢的:)

If you'd like to improve the true randomness of the shuffle, please see the comments for more details. I particularly like Fishes Yates Shuffle but you can do some research an implement whatever you like :)

PHP的 shuffle 将对数组的索引重新排序–即,它会改变输入数组.

PHP's shuffle will reorder the indicies of your array – ie, it mutates the input array.

如果您想保留输入数组并对其进行随机整理的副本,我已经花了一些时间来实现Fisher-Yates 算法.

If you would like to preserve the input array and make a shuffled copy of it, I've taken the time to implement Fisher-Yates "inside-out" algorithm for you.

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结果进行排序


Alternatively, you could sort the MySQL result using

ORDER BY RAND()

此操作的性能将取决于许多其他因素,但是如果查询足够简单并且结果足够小,那么就不成问题了.

The performance of this is going to depend on a lot of other factors, but if the query is simple enough and the result is small enough, it shouldn't be an issue.

如果您希望采用这种方法,请快速搜索一下.您会发现很多信息和技巧,可以优化SQL中的随机排序.

If you're looking to take this approach, do some quick googling. You'll find lots of information and tricks to optimizing random sorts in SQL.

这篇关于随机遍历数组,而无需提取重复值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆