在列表中访问随机项目
我有一个ArrayList,我需要能够点击一个button,然后从该列表中随机挑选一个string,并将其显示在一个消息框中。
我怎么去做这个?
-
在某处创build一个
Random
类的实例。 请注意,每次您需要一个随机数字时,不要创build一个新的实例。 您应该重新使用旧的实例来实现生成的数字的一致性。 你可以有一个static
字段(注意线程安全问题):static Random rnd = new Random();
-
要求
Random
实例为您提供一个随机数,其中包含ArrayList
中项目数量的最大值:int r = rnd.Next(list.Count);
-
显示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())); }