Respuestas:
Crea una instancia de Random
clase en alguna parte. Tenga en cuenta que es bastante importante no crear una nueva instancia cada vez que necesite un número aleatorio. Debe reutilizar la instancia anterior para lograr uniformidad en los números generados. Puede tener un static
campo en alguna parte (tenga cuidado con los problemas de seguridad del hilo):
static Random rnd = new Random();
Pídale a la Random
instancia que le dé un número aleatorio con el máximo de la cantidad de elementos en ArrayList
:
int r = rnd.Next(list.Count);
Mostrar la cadena:
MessageBox.Show((string)list[r]);
Next(max)
llamada es exclusivo.
Usualmente uso esta pequeña colección de métodos de extensión:
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());
}
}
Para una lista fuertemente tipada, esto le permitiría escribir:
var strings = new List<string>();
var randomString = strings.PickRandom();
Si todo lo que tiene es una ArrayList, puede lanzarla:
var strings = myArrayList.Cast<string>();
return list[rnd.Next(list.Count)];
Random
en estado estático en su lugar.
Tu puedes hacer:
list.OrderBy(x => Guid.NewGuid()).FirstOrDefault()
Crea una Random
instancia:
Random rnd = new Random();
Obtener una cadena aleatoria:
string s = arraylist[rnd.Next(arraylist.Count)];
Sin embargo, recuerde que si hace esto con frecuencia, debe reutilizar el Random
objeto. Póngalo como campo estático en la clase para que se inicialice solo una vez y luego acceda a él.
O una clase de extensión simple como esta:
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)];
}
}
Entonces solo llame:
myList.RandomElement();
Funciona para matrices también.
Evitaría llamar OrderBy()
ya que puede ser costoso para colecciones más grandes. Utilice colecciones indexadas como List<T>
o matrices para este propósito.
IList
por lo que la segunda sobrecarga es innecesaria.
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());
maxValue
parámetro del método Next
debe ser solo un número de elementos en una lista, no menos uno, porque de acuerdo con una documentación " maxValue es el límite superior exclusivo del número aleatorio ".
He estado usando este ExtensionMethod por un tiempo:
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;
}
Sugeriré un enfoque diferente, si el orden de los elementos dentro de la lista no es importante en la extracción (y cada elemento debe seleccionarse solo una vez), entonces, en lugar de uno List
, puede usar uno ConcurrentBag
que es una colección desordenada y segura de hilos objetos:
var bag = new ConcurrentBag<string>();
bag.Add("Foo");
bag.Add("Boo");
bag.Add("Zoo");
El manejador de eventos:
string result;
if (bag.TryTake(out result))
{
MessageBox.Show(result);
}
El TryTake
intentará extraer un objeto "al azar" de la colección no ordenada.
Necesitaba más elementos en lugar de solo uno. Entonces, escribí esto:
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;
}
Con esto, puede obtener elementos cuántos desea de forma aleatoria como esta:
var _allItems = new List<TModel>()
{
// ...
// ...
// ...
}
var randomItemList = _allItems.GetSelectedRandom(10);
Imprimir al azar el nombre del país desde el archivo JSON.
Modelo:
public class Country
{
public string Name { get; set; }
public string Code { get; set; }
}
Implementación:
string filePath = Path.GetFullPath(Path.Combine(Environment.CurrentDirectory, @"..\..\..\")) + @"Data\Country.json";
string _countryJson = File.ReadAllText(filePath);
var _country = JsonConvert.DeserializeObject<List<Country>>(_countryJson);
int index = random.Next(_country.Count);
Console.WriteLine(_country[index].Name);
Por qué no [2]:
public static T GetRandom<T>(this List<T> list)
{
return list[(int)(DateTime.Now.Ticks%list.Count)];
}