Возьмите 30 случайных элементов из списка - PullRequest
0 голосов
/ 05 июня 2019

У меня есть список строк, содержащих множество хэштегов с текстами.бывший #csharp # Java и т. д.каждый хэштег является собственной строкой в ​​списке.Теперь я хочу в случайном порядке всегда console.writeline 30 пунктов этого списка.

Список


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

Writeline


 foreach (var x in Hashtags) {

                Console.WriteLine(x);
            }

В идеале я никогда не хочу иметь один и тот же хэштег в случайном порядке 30.

Ответы [ 4 ]

5 голосов
/ 05 июня 2019

Вы должны попробовать это:

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();
2 голосов
/ 05 июня 2019

Это должно сделать.Он эффективен, поскольку тасует только необходимое количество предметов, а не всю коллекцию.Вы передаете, сколько элементов вы хотите извлечь из массива в качестве параметра (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);
}
0 голосов
/ 05 июня 2019

Работаю сам, немного более многословно, но, надеюсь, легче следовать.

 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); 
 }
0 голосов
/ 05 июня 2019

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])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...