How to access random item in list?

后端 未结 12 982
滥情空心
滥情空心 2020-11-22 15:20

I have an ArrayList, and I need to be able to click a button and then randomly pick out a string from that list and display it in a messagebox.

How would I go about

相关标签:
12条回答
  • 2020-11-22 15:32

    Why not:

    public static T GetRandom<T>(this IEnumerable<T> list)
    {
       return list.ElementAt(new Random(DateTime.Now.Millisecond).Next(list.Count()));
    }
    
    0 讨论(0)
  • 2020-11-22 15:33

    I'll suggest different approach, If the order of the items inside the list is not important at extraction (and each item should be selected only once), then instead of a List you can use a ConcurrentBag which is a thread-safe, unordered collection of objects:

    var bag = new ConcurrentBag<string>();
    bag.Add("Foo");
    bag.Add("Boo");
    bag.Add("Zoo");
    

    The EventHandler:

    string result;
    if (bag.TryTake(out result))
    {
        MessageBox.Show(result);
    }
    

    The TryTake will attempt to extract an "random" object from the unordered collection.

    0 讨论(0)
  • 2020-11-22 15:33

    I needed to more item instead of just one. So, I wrote this:

    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;
    }
    

    With this, you can get elements how many you want as randomly like this:

    var _allItems = new List<TModel>()
    {
        // ...
        // ...
        // ...
    }
    
    var randomItemList = _allItems.GetSelectedRandom(10); 
    
    0 讨论(0)
  • 2020-11-22 15:36

    I have been using this ExtensionMethod for a while:

    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;
    }
    
    0 讨论(0)
  • 2020-11-22 15:37
    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());
    
    0 讨论(0)
  • 2020-11-22 15:39

    Or simple extension class like this:

    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)];
        }
    }
    

    Then just call:

    myList.RandomElement();
    

    Works for arrays as well.

    I would avoid calling OrderBy() as it can be expensive for larger collections. Use indexed collections like List<T> or arrays for this purpose.

    0 讨论(0)
提交回复
热议问题