Câu trả lời:
Tạo một thể hiện của Random
lớp ở đâu đó. Lưu ý rằng điều quan trọng là không tạo một phiên bản mới mỗi khi bạn cần một số ngẫu nhiên. Bạn nên sử dụng lại thể hiện cũ để đạt được sự đồng nhất trong các số được tạo. Bạn có thể có một static
trường ở đâu đó (cẩn thận về các vấn đề an toàn của luồng):
static Random rnd = new Random();
Yêu cầu Random
cá thể cung cấp cho bạn một số ngẫu nhiên với số lượng mục tối đa trong ArrayList
:
int r = rnd.Next(list.Count);
Hiển thị chuỗi:
MessageBox.Show((string)list[r]);
Next(max)
cuộc gọi là độc quyền.
Tôi thường sử dụng bộ sưu tập nhỏ các phương thức mở rộng này:
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());
}
}
Đối với một danh sách được gõ mạnh, điều này sẽ cho phép bạn viết:
var strings = new List<string>();
var randomString = strings.PickRandom();
Nếu tất cả những gì bạn có là một ArrayList, bạn có thể truyền nó:
var strings = myArrayList.Cast<string>();
return list[rnd.Next(list.Count)];
Random
Thay vào đó, hãy xem xét việc giữ một thể hiện ở trạng thái tĩnh.
Bạn có thể làm:
list.OrderBy(x => Guid.NewGuid()).FirstOrDefault()
Tạo một Random
ví dụ:
Random rnd = new Random();
Lấy một chuỗi ngẫu nhiên:
string s = arraylist[rnd.Next(arraylist.Count)];
Tuy nhiên, hãy nhớ rằng nếu bạn làm điều này thường xuyên, bạn nên sử dụng lại Random
đối tượng. Đặt nó dưới dạng một trường tĩnh trong lớp để nó được khởi tạo chỉ một lần và sau đó truy cập nó.
Hoặc lớp mở rộng đơn giản như thế này:
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)];
}
}
Sau đó chỉ cần gọi:
myList.RandomElement();
Làm việc cho mảng là tốt.
Tôi sẽ tránh gọi OrderBy()
vì nó có thể tốn kém cho các bộ sưu tập lớn hơn. Sử dụng các bộ sưu tập được lập chỉ mục như List<T>
hoặc mảng cho mục đích này.
IList
nên quá tải thứ hai là không cần thiế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());
maxValue
tham số của phương thức Next
chỉ nên là một số phần tử trong danh sách, không trừ đi một phần, bởi vì theo tài liệu " maxValue là giới hạn trên độc quyền của số ngẫu nhiên ".
Tôi đã sử dụng ExtensionMethod này một thời gian:
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;
}
Tôi sẽ đề xuất cách tiếp cận khác nhau, Nếu thứ tự của các mục trong danh sách không quan trọng khi trích xuất (và mỗi mục chỉ nên được chọn một lần), thì thay vì List
bạn có thể sử dụng một mục ConcurrentBag
là bộ sưu tập không có thứ tự, an toàn theo chủ đề các đối tượng:
var bag = new ConcurrentBag<string>();
bag.Add("Foo");
bag.Add("Boo");
bag.Add("Zoo");
Người tổ chức sự kiện:
string result;
if (bag.TryTake(out result))
{
MessageBox.Show(result);
}
Ý TryTake
chí sẽ cố gắng trích xuất một đối tượng "ngẫu nhiên" từ bộ sưu tập không có thứ tự.
Tôi cần nhiều mục hơn thay vì chỉ một. Vì vậy, tôi đã viết điều này:
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;
}
Với điều này, bạn có thể nhận được các yếu tố có bao nhiêu bạn muốn ngẫu nhiên như thế này:
var _allItems = new List<TModel>()
{
// ...
// ...
// ...
}
var randomItemList = _allItems.GetSelectedRandom(10);
In ngẫu nhiên tên quốc gia từ tệp JSON.
Mô hình:
public class Country
{
public string Name { get; set; }
public string Code { get; set; }
}
Triển khai:
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);