在列表中访问随机项目

我有一个ArrayList,我需要能够点击一个button,然后从该列表中随机挑选一个string,并将其显示在一个消息框中。

我怎么去做这个?

  1. 在某处创build一个Random类的实例。 请注意,每次您需要一个随机数字时,不要创build一个新的实例。 您应该重新使用旧的实例来实现生成的数字的一致性。 你可以有一个static字段(注意线程安全问题):

     static Random rnd = new Random(); 
  2. 要求Random实例为您提供一个随机数,其中包含ArrayList中项目数量的最大值:

     int r = rnd.Next(list.Count); 
  3. 显示string:

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

对于一个强types的列表,这将允许你写:

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

如果你只有一个ArrayList,你可以投它:

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

你可以做:

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

创build一个Random实例:

 Random rnd = new Random(); 

取一个随机string:

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

记住,如果你经常这样做,你应该重新使用Random对象。 把它作为一个静态字段,所以它只初始化一次,然后访问它。

或者像这样简单的扩展类:

 public static class ColectionExtension { 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 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; } 

为什么不:

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