从列表中选取30个随机元素

时间:2019-06-05 12:14:17

标签: c# list random

我有一个字符串列表,其中包含带有文本的#标签。 例如#csharp #java等等。 每个主题标签是列表中自己的字符串。我现在想随机地总是console.writeline该列表的30个项目。

列表


List<string> Hashtags = new List<string>();

写信


 foreach (var x in Hashtags) {

                Console.WriteLine(x);
            }

理想情况下,我永远都不想在随机30中使用相同的主题标签。

4 个答案:

答案 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); 
 }