Respostas:
Crie uma instância da Random
classe em algum lugar. Observe que é muito importante não criar uma nova instância sempre que você precisar de um número aleatório. Você deve reutilizar a instância antiga para obter uniformidade nos números gerados. Você pode ter um static
campo em algum lugar (tenha cuidado com os problemas de segurança do encadeamento):
static Random rnd = new Random();
Peça à Random
instância para fornecer um número aleatório com o máximo do número de itens no ArrayList
:
int r = rnd.Next(list.Count);
Exiba a sequência:
MessageBox.Show((string)list[r]);
Next(max)
chamada é exclusivo.
Eu costumo usar esta pequena coleção de métodos de extensão:
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 uma lista fortemente tipada, isso permitiria escrever:
var strings = new List<string>();
var randomString = strings.PickRandom();
Se tudo o que você tem é um ArrayList, é possível convertê-lo:
var strings = myArrayList.Cast<string>();
return list[rnd.Next(list.Count)];
Random
no estado estático.
Você pode fazer:
list.OrderBy(x => Guid.NewGuid()).FirstOrDefault()
Crie uma Random
instância:
Random rnd = new Random();
Busque uma sequência aleatória:
string s = arraylist[rnd.Next(arraylist.Count)];
Lembre-se, porém, que se você fizer isso com frequência, deverá reutilizar o Random
objeto. Coloque-o como um campo estático na classe, para que seja inicializado apenas uma vez e depois acesse-o.
Ou classe de extensão simples 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)];
}
}
Em seguida, basta ligar para:
myList.RandomElement();
Funciona para matrizes também.
Eu evitaria ligar OrderBy()
, pois pode ser caro para coleções maiores. Use coleções indexadas como List<T>
ou matrizes para esse fim.
IList
portanto a segunda sobrecarga é desnecessária.
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 do método Next
deve ser apenas um número de elementos em uma lista, não menos um, porque de acordo com a documentação " maxValue é o limite superior exclusivo do número aleatório ".
Estou usando este ExtensionMethod há algum tempo:
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;
}
Sugiro uma abordagem diferente: se a ordem dos itens dentro da lista não for importante na extração (e cada item deve ser selecionado apenas uma vez), em vez de um, List
você pode usar um ConcurrentBag
que é uma coleção não ordenada e segura de threads objetos:
var bag = new ConcurrentBag<string>();
bag.Add("Foo");
bag.Add("Boo");
bag.Add("Zoo");
O EventHandler:
string result;
if (bag.TryTake(out result))
{
MessageBox.Show(result);
}
O TryTake
tentará extrair um objeto "aleatório" da coleção não ordenada.
Eu precisava de mais itens em vez de apenas um. Então, eu escrevi isso:
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;
}
Com isso, você pode obter elementos quantos quiser, de forma aleatória assim:
var _allItems = new List<TModel>()
{
// ...
// ...
// ...
}
var randomItemList = _allItems.GetSelectedRandom(10);
Imprimindo aleatoriamente o nome do país a partir do arquivo JSON.
Modelo:
public class Country
{
public string Name { get; set; }
public string Code { get; set; }
}
Implementação:
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 que não [2]:
public static T GetRandom<T>(this List<T> list)
{
return list[(int)(DateTime.Now.Ticks%list.Count)];
}