如何访问列表中的随机项?
我有一个ArrayList,我需要能够单击一个按钮然后从该列表中随机挑出一个字符串并将其显示在消息框中。
我该怎么做呢?
-
在某处创建一个
Random
类的实例。 请注意,每次需要随机数时都不要创建新实例。 您应该重用旧实例以实现生成数字的一致性。 你可以在某处有一个static
字段(注意线程安全问题):static Random rnd = new Random();
-
请求
Random
实例为您提供一个随机数,其中包含ArrayList
中项目数的最大值:int r = rnd.Next(list.Count);
-
显示字符串:
MessageBox.Show((string)list[r]);
我通常使用这个小扩展方法集合:
public static class EnumerableExtension { public static T PickRandom(this IEnumerable source) { return source.PickRandom(1).Single(); } public static IEnumerable PickRandom (this IEnumerable source, int count) { return source.Shuffle().Take(count); } public static IEnumerable Shuffle (this IEnumerable source) { return source.OrderBy(x => Guid.NewGuid()); } }
对于强类型列表,这将允许您编写:
var strings = new List(); var randomString = strings.PickRandom();
如果您拥有的只是一个ArrayList,则可以将其强制转换:
var strings = myArrayList.Cast();
你可以做:
list.OrderBy(x => Guid.NewGuid()).FirstOrDefault()
创建一个Random
实例:
Random rnd = new Random();
获取随机字符串:
string s = arraylist[rnd.Next(arraylist.Count)];
但请记住,如果经常这样做,则应重新使用Random
对象。 将它作为类中的静态字段,因此它只初始化一次然后访问它。
或者像这样的简单扩展类:
public static class CollectionExtension { private static Random rng = new Random(); public static T RandomElement(this IList list) { return list[rng.Next(list.Count)]; } public static T RandomElement (this T[] array) { return array[rng.Next(array.Length)]; } }
然后打电话:
myList.RandomElement();
也适用于数组。
我会避免调用OrderBy()
因为它对于较大的集合来说可能是昂贵的。 为此目的使用List
或数组等索引集合。
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(this IEnumerable list) { return list.ElementAt(new Random(DateTime.Now.Millisecond).Next(list.Count())); }
我需要更多项而不是一项。 所以,我写了这个:
public static TList GetSelectedRandom(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() { // ... // ... // ... } var randomItemList = _allItems.GetSelectedRandom(10);
我一直在使用这个ExtensionMethod:
public static IEnumerable GetRandom (this IEnumerable 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(this List list) { return list[(int)(DateTime.Now.Ticks%list.Count)]; }