ฉันมี ArrayList และฉันต้องสามารถคลิกปุ่มแล้วสุ่มเลือกสตริงจากรายการนั้นและแสดงในกล่องข้อความ
ฉันจะทำสิ่งนี้อย่างไร
ฉันมี ArrayList และฉันต้องสามารถคลิกปุ่มแล้วสุ่มเลือกสตริงจากรายการนั้นและแสดงในกล่องข้อความ
ฉันจะทำสิ่งนี้อย่างไร
คำตอบ:
สร้างตัวอย่างของการRandom
เรียนที่ไหนสักแห่ง โปรดทราบว่ามันสำคัญมากที่จะไม่สร้างอินสแตนซ์ใหม่ทุกครั้งที่คุณต้องการหมายเลขสุ่ม คุณควรใช้อินสแตนซ์เก่าเพื่อให้เกิดความสม่ำเสมอในตัวเลขที่สร้างขึ้น คุณสามารถมีstatic
ฟิลด์ที่ใดที่หนึ่ง (ระมัดระวังเกี่ยวกับปัญหาความปลอดภัยของเธรด):
static Random rnd = new Random();
ขอให้Random
อินสแตนซ์ให้หมายเลขสุ่มกับจำนวนสูงสุดของรายการในArrayList
:
int r = rnd.Next(list.Count);
แสดงสตริง:
MessageBox.Show((string)list[r]);
Next(max)
โทรเป็นเอกสิทธิ์
ฉันมักจะใช้วิธีการขยายขนาดเล็กนี้:
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());
}
}
สำหรับรายการที่พิมพ์อย่างมากสิ่งนี้จะอนุญาตให้คุณเขียน:
var strings = new List<string>();
var randomString = strings.PickRandom();
หากสิ่งที่คุณมีคือ ArrayList คุณสามารถส่งได้:
var strings = myArrayList.Cast<string>();
return list[rnd.Next(list.Count)];
Random
ในสถานะคงที่แทน
คุณทำได้:
list.OrderBy(x => Guid.NewGuid()).FirstOrDefault()
สร้างRandom
ตัวอย่าง:
Random rnd = new Random();
ดึงสตริงแบบสุ่ม:
string s = arraylist[rnd.Next(arraylist.Count)];
โปรดจำไว้ว่าหากคุณทำเช่นนี้บ่อยครั้งคุณควรใช้Random
วัตถุนั้นอีกครั้ง วางไว้เป็นเขตข้อมูลแบบคงที่ในชั้นเรียนเพื่อให้เริ่มต้นได้เพียงครั้งเดียวแล้วเข้าถึง
หรือคลาสเสริมส่วนขยายแบบนี้:
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)];
}
}
จากนั้นเพียงแค่โทร:
myList.RandomElement();
ทำงานสำหรับอาร์เรย์เช่นกัน
ฉันจะหลีกเลี่ยงการโทรOrderBy()
เพราะอาจมีราคาแพงสำหรับคอลเลกชันขนาดใหญ่ ใช้คอลเลกชันที่มีการจัดทำดัชนีเช่นList<T>
หรืออาร์เรย์เพื่อจุดประสงค์นี้
IList
ดังนั้นการโอเวอร์โหลดครั้งที่สองจึงไม่จำเป็น
ทำไมจะไม่ล่ะ:
public static T GetRandom<T>(this IEnumerable<T> list)
{
return list.ElementAt(new Random(DateTime.Now.Millisecond).Next(list.Count()));
}
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
พารามิเตอร์ของวิธีการNext
ควรเป็นเพียงจำนวนขององค์ประกอบในรายการไม่ลบหนึ่งเพราะตามเอกสาร " maxValue เป็นขอบเขตเฉพาะพิเศษของหมายเลขสุ่ม "
ฉันใช้ส่วนขยายนี้มาระยะหนึ่งแล้ว:
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;
}
ฉันจะแนะนำวิธีการที่แตกต่างกันหากลำดับของรายการในรายการไม่สำคัญในการแยก (และแต่ละรายการควรเลือกเพียงครั้งเดียว) จากนั้นแทนที่จะใช้List
คุณสามารถใช้ชุดConcurrentBag
ที่ปลอดภัยต่อการเรียงลำดับ วัตถุ:
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);
}
TryTake
จะพยายามที่จะดึงวัตถุ "สุ่ม" จากการเก็บเรียงลำดับ
ฉันต้องการไอเท็มเพิ่มเติมมากกว่าหนึ่งอัน ดังนั้นฉันจึงเขียนสิ่งนี้:
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;
}
ด้วยสิ่งนี้คุณจะได้รับองค์ประกอบที่คุณต้องการแบบสุ่มดังนี้
var _allItems = new List<TModel>()
{
// ...
// ...
// ...
}
var randomItemList = _allItems.GetSelectedRandom(10);
การพิมพ์ชื่อประเทศแบบสุ่มจากไฟล์ JSON
รุ่น:
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);
ทำไมไม่ [2]:
public static T GetRandom<T>(this List<T> list)
{
return list[(int)(DateTime.Now.Ticks%list.Count)];
}