我有这段代码:
public async Task ShowTimedCard()
{
phrase = phrases[(int)AS.rand.Next(phrases.Count)];
它会获得一个随机数,然后从phrases
中选择一个短语,该短语是phrase
行的列表。列表中有后台进程添加和删除的项目。
每个短语都有一个Id
字段。由于其他原因,我无法从列表中删除我使用的短语。
有时ShowTimedCard会连续两次选择相同的短语,所以我决定将lastPhrase信息存储在这样的静态变量中:
AS.phrase.id = phrase.id
如果phrases
列表中有多个项目,那么我怎么能这样做呢?它不会连续两次选择相同的短语 ?我在考虑某种while循环或直到循环但不确定如何实现它。我想它需要比较短语.Id与AS.phrase.id
答案 0 :(得分:1)
显示您创建rand的位置
您应该只创建一次并重复使用
我敢打赌,你正在创造新的,而且没有足够的时间来获得新的种子
好的,我可能错过了这个问题
使用Yates shuffle
重新排列List这是字节,但你明白了
for (byte i = (byte)(count - 1); i >= 1; i--)
{
byte k = (byte)rand.Next(i + 1);
if (k != i)
{ // exchange the values
curVal = deck[i];
deck[i] = deck[k];
deck[k] = curVal;
}
}
或者将使用过的id存储在hashset
中Random rand = new Random();
HashSet<int> hs = new HashSet<int>();
int next;
while (hs.Contains(next = rand.Next(12))) { }
hs.Add(next)
移动目标
while (next = rand.Next(12) == lastNext) { }
lastNext = next;
答案 1 :(得分:0)
听起来你真正想做的是随机排序,然后你就可以连续拍摄。这将确保您在显示所有其他项目之前看不到任何项目,但它们不会按照添加顺序显示:
// Shuffle our list of phrases, so they're in a random order
var rnd = new Random();
phrases = phrases.OrderBy(p => rnd.NextDouble()).ToList();
然后,您可以随时重新随机播放列表,例如添加新项目或者到达列表末尾时。
这是一个使用整数的快速演示:
// Create a list of consecutive integers and display it
var numbers = Enumerable.Range(1, 30).ToList();
Console.WriteLine("Original list:");
Console.WriteLine(string.Join(", ", numbers));
// Shuffle the list and display it again
var rnd = new Random();
numbers = numbers.OrderBy(n => rnd.NextDouble()).ToList();
Console.WriteLine("\nShuffled list:");
Console.WriteLine(string.Join(", ", numbers));
<强>输出强>