Как получить доступ к случайному элементу в списке?



У меня есть ArrayList, и мне нужно иметь возможность нажать кнопку, а затем случайным образом выбрать строку из этого списка и отобразить ее в окне сообщений.



Как бы я это сделал?

470   10  

10 ответов:

  1. создать экземпляр Random класса где-то. Обратите внимание, что это очень важно не создавать новый экземпляр каждый раз, когда вам нужно случайное число. Вы должны повторно использовать старый экземпляр для достижения единообразия в сгенерированных числах. Вы можете иметь static поле где-то (будьте осторожны с вопросами безопасности потоков):

    static Random rnd = new Random();
    
  2. задать вопрос Random экземпляр, чтобы дать вам случайное число с максимальным количеством элементов в ArrayList:

    int r = rnd.Next(list.Count);
    
  3. отобразить строку:

    MessageBox.Show((string)list[r]);
    

Я обычно использую эту небольшую коллекцию методов расширения:

public static class EnumerableExtension
{
    public static T PickRandom<T>(this IEnumerable<T> source)
    {
        return source.PickRandom(1).Single();
    }

    public static IEnumerable<T> PickRandom<T>(this IEnumerable<T> source, int count)
    {
        return source.Shuffle().Take(count);
    }

    public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> source)
    {
        return source.OrderBy(x => Guid.NewGuid());
    }
}

для строго типизированного списка это позволит вам написать:

var strings = new List<string>();
var randomString = strings.PickRandom();

Если все, что у вас есть, это ArrayList, вы можете бросить его:

var strings = myArrayList.Cast<string>();

вы можете сделать:

list.OrderBy(x => Guid.NewGuid()).FirstOrDefault()

создать Random например:

Random rnd = new Random();

выборка случайной строки:

string s = arraylist[rnd.Next(arraylist.Count)];

помните, что если вы делаете это часто, вы должны использовать

или простой класс расширения, как это:

public static class CollectionExtension
{
    private static Random rng = new Random();

    public static T RandomElement<T>(this IList<T> list)
    {
        return list[rng.Next(list.Count)];
    }

    public static T RandomElement<T>(this T[] array)
    {
        return array[rng.Next(array.Length)];
    }
}

тогда просто звоните:

myList.RandomElement();

работает и для массивов.

Я бы не стал звонить OrderBy() как это может быть дорого для больших коллекций. Используйте индексированные коллекции, такие как List<T> или массивы для этой цели.

ArrayList ar = new ArrayList();
        ar.Add(1);
        ar.Add(5);
        ar.Add(25);
        ar.Add(37);
        ar.Add(6);
        ar.Add(11);
        ar.Add(35);
        Random r = new Random();
        int index = r.Next(0,ar.Count-1);
        MessageBox.Show(ar[index].ToString());

почему бы и нет:

public static T GetRandom<T>(this IEnumerable<T> list)
{
   return list.ElementAt(new Random(DateTime.Now.Millisecond).Next(list.Count()));
}

мне нужно было больше элемента, а не только один. Итак, я написал следующее:

public static TList GetSelectedRandom<TList>(this TList list, int count)
       where TList : IList, new()
{
    var r = new Random();
    var rList = new TList();
    while (count > 0 && list.Count > 0)
    {
        var n = r.Next(0, list.Count);
        var e = list[n];
        rList.Add(e);
        list.RemoveAt(n);
        count--;
    }

    return rList;
}

С помощью этого, вы можете получить элементы, сколько вы хотите, как случайным образом, как это:

var _allItems = new List<TModel>()
{
    // ...
    // ...
    // ...
}

var randomItemList = _allItems.GetSelectedRandom(10); 

Я использую этот ExtensionMethod в течение некоторого времени:

public static IEnumerable<T> GetRandom<T>(this IEnumerable<T> list, int count)
{
    if (count <= 0)
      yield break;
    var r = new Random();
    int limit = (count * 10);
    foreach (var item in list.OrderBy(x => r.Next(0, limit)).Take(count))
      yield return item;
}

почему бы и нет[2]:

public static T GetRandom<T>(this List<T> list)
{
     return list[(int)(DateTime.Now.Ticks%list.Count)];
}

Comments

    Ничего не найдено.