Jawaban:
Buat instance Random
kelas di suatu tempat. Perhatikan bahwa sangat penting untuk tidak membuat instance baru setiap kali Anda membutuhkan nomor acak. Anda harus menggunakan kembali instance lama untuk mencapai keseragaman dalam angka yang dihasilkan. Anda dapat memiliki static
bidang di suatu tempat (hati-hati dengan masalah keamanan utas):
static Random rnd = new Random();
Minta Random
instance untuk memberi Anda nomor acak dengan maksimum jumlah item dalam ArrayList
:
int r = rnd.Next(list.Count);
Tampilkan string:
MessageBox.Show((string)list[r]);
Next(max)
panggilan ini eksklusif.
Saya biasanya menggunakan kumpulan kecil metode ekstensi ini:
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());
}
}
Untuk daftar yang sangat diketik, ini memungkinkan Anda untuk menulis:
var strings = new List<string>();
var randomString = strings.PickRandom();
Jika yang Anda miliki hanyalah ArrayList, Anda dapat mengirimkannya:
var strings = myArrayList.Cast<string>();
return list[rnd.Next(list.Count)];
Random
dalam keadaan statis sebagai gantinya.
Anda dapat melakukan:
list.OrderBy(x => Guid.NewGuid()).FirstOrDefault()
Buat sebuah Random
instance:
Random rnd = new Random();
Ambil string acak:
string s = arraylist[rnd.Next(arraylist.Count)];
Ingat juga, bahwa jika Anda sering melakukan ini, Anda harus menggunakan kembali Random
objek. Letakkan sebagai bidang statis di kelas sehingga hanya diinisialisasi satu kali dan kemudian mengaksesnya.
Atau kelas ekstensi sederhana seperti ini:
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)];
}
}
Lalu panggil saja:
myList.RandomElement();
Berfungsi untuk array juga.
Saya akan menghindari menelepon OrderBy()
karena bisa mahal untuk koleksi yang lebih besar. Gunakan koleksi yang diindeks seperti List<T>
atau array untuk tujuan ini.
IList
sehingga kelebihan kedua tidak perlu.
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
parameter metode Next
harus hanya sejumlah elemen dalam daftar, bukan minus satu, karena menurut dokumentasi " maxValue adalah batas atas eksklusif dari nomor acak ".
Saya telah menggunakan ExtensionMethod ini untuk sementara waktu:
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;
}
Saya akan menyarankan pendekatan yang berbeda, Jika urutan item di dalam daftar tidak penting saat ekstraksi (dan setiap item harus dipilih hanya sekali), maka alih-alih List
Anda dapat menggunakan ConcurrentBag
yang merupakan koleksi thread-safe, unordered dari benda:
var bag = new ConcurrentBag<string>();
bag.Add("Foo");
bag.Add("Boo");
bag.Add("Zoo");
EventHandler:
string result;
if (bag.TryTake(out result))
{
MessageBox.Show(result);
}
The TryTake
akan berupaya mengambil sebuah "acak" objek dari koleksi unordered.
Saya perlu lebih banyak barang, bukan hanya satu. Jadi, saya menulis ini:
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;
}
Dengan ini, Anda bisa mendapatkan elemen berapa banyak yang Anda inginkan secara acak seperti ini:
var _allItems = new List<TModel>()
{
// ...
// ...
// ...
}
var randomItemList = _allItems.GetSelectedRandom(10);
Mencetak nama negara secara acak dari file JSON.
Model:
public class Country
{
public string Name { get; set; }
public string Code { get; set; }
}
Implementaton:
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);
Kenapa tidak [2]:
public static T GetRandom<T>(this List<T> list)
{
return list[(int)(DateTime.Now.Ticks%list.Count)];
}