Accede al elemento aleatorio en la lista

Tengo una ArrayList, y necesito poder hacer clic en un botón y luego seleccionar aleatoriamente una cadena de esa lista y mostrarla en un cuadro de mensaje.

¿Cómo voy a hacer esto?

  1. Crea una instancia de clase Random alguna parte. Tenga en cuenta que es muy importante no crear una nueva instancia cada vez que necesite un número aleatorio. Debe reutilizar la instancia anterior para lograr la uniformidad en los números generados. Puede tener un campo static alguna parte (tenga cuidado con los problemas de seguridad de subprocesos):

     static Random rnd = new Random(); 
  2. Pídale a la instancia Random que le dé un número aleatorio con el máximo de la cantidad de elementos en ArrayList :

     int r = rnd.Next(list.Count); 
  3. Mostrar la cadena:

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

Usualmente uso esta pequeña colección de métodos de extensión:

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

Para una lista fuertemente tipada, esto le permitirá escribir:

 var strings = new List(); var randomString = strings.PickRandom(); 

Si todo lo que tiene es una ArrayList, puede convertirlo:

 var strings = myArrayList.Cast(); 

Tu puedes hacer:

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

Crea una instancia Random :

 Random rnd = new Random(); 

Obtener una cadena aleatoria:

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

Sin embargo, recuerde que si lo hace con frecuencia, debe volver a utilizar el objeto Random . Póngalo como un campo estático en la clase, de modo que se inicialice solo una vez y luego acceda a él.

O clase de extensión simple como esta:

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

Entonces solo llame:

 myList.RandomElement(); 

Funciona para arreglos también.

OrderBy() llamar a OrderBy() ya que puede ser costoso para colecciones más grandes. Use colecciones indexadas como List o matrices para este propósito.

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

Por qué no:

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

Necesitaba más artículo en lugar de solo uno. Entonces, escribí esto:

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

Con esto, puedes obtener elementos que quieras de forma aleatoria como este:

 var _allItems = new List() { // ... // ... // ... } var randomItemList = _allItems.GetSelectedRandom(10); 

He estado usando este ExtensionMethod por un tiempo:

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