我有一个字符串列表,其中包含带有文本的#标签。 例如#csharp #java等等。 每个主题标签是列表中自己的字符串。我现在想随机地总是console.writeline该列表的30个项目。
列表
List<string> Hashtags = new List<string>();
写信
foreach (var x in Hashtags) {
Console.WriteLine(x);
}
理想情况下,我永远都不想在随机30中使用相同的主题标签。
答案 0 :(得分:5)
您应该尝试以下操作:
var rnd = new Random();
foreach (var x in Hashtags.OrderBy(x => rnd.Next()).Take(30))
{
Console.WriteLine(x);
}
这具有O(n^2)
的复杂性,但易于阅读。
如果您想提高效率,请尝试使用Fisher-Yates Shuffle,它是O(n)
,但可读性较差:
var take = 30;
var rnd = new Random();
for (var i = 0; i < (Hashtags.Count < take ? Hashtags.Count : take); i++)
{
var j = rnd.Next(Hashtags.Count);
(Hashtags[i], Hashtags[j]) = (Hashtags[j], Hashtags[i]);
}
foreach (var x in Hashtags.Take(take))
{
Console.WriteLine(x);
}
但是请记住,最好每个线程实例化一次Random
,所以这是一个更好的方法:
[ThreadStatic]
private static Random rnd = new Random();
答案 1 :(得分:2)
这应该做。这是有效的,因为它只会随机播放所需数量的项目,而不是整个集合。您将要从数组中获取多少个元素作为参数(elementCount
。
private static Random randomGenerator = new Random();
static void Main()
{
var hashtags = new List<string>() { "c#", "javascript", "ef", "asp.net" };
var result = GetRandomItems<string>(hashtags, 2);
foreach (var item in result)
{
Console.WriteLine(item);
}
}
private static IEnumerable<T> GetRandomItems<T>(IEnumerable<T> collection, int elementCount)
{
var collectionCount = collection.Count();
if (elementCount > collectionCount)
{
elementCount = collectionCount;
}
var collectionCopy = collection.ToList();
var randomIndex = randomGenerator.Next(0, collectionCopy.Count);
for (var index = 0; index < elementCount; index++)
{
var tempElement = collectionCopy[index];
collectionCopy[index] = collectionCopy[randomIndex];
collectionCopy[randomIndex] = tempElement;
randomIndex = randomGenerator.Next(index + 1, collectionCopy.Count);
}
return collectionCopy.Take(elementCount);
}
答案 2 :(得分:0)
拨打30次Random.next
https://docs.microsoft.com/en-us/dotnet/api/system.random.next
var random = new Random();
//calls this n times in a loop:
Console.writeline(Hashtags[random.next(Hashtags.Count])
答案 3 :(得分:0)
让它自己工作,更详细些,但希望更容易理解。
var random = new Random();
var uniques = Hashtags;
for (var i = 0; i < 30; i++) {
var index = random.Next(0, uniques.Count());
Console.WriteLine(uniques[index]);
uniques.RemoveAt(index);
}