本文提供对Random的封装,简化并扩展了其功能
- 获取随机数,确保同时调用不会重复
//new Random().Next(5); RandomTask.Next(5);
- 从一个列表中,随机获取其中某个值
List
lsTest = new List { "1","2","3","4","5" }; string randomValue = RandomTask.PickOne(lsTest); Console.WriteLine(randomValue); - 从一个列表中,随机获取其中多个值
List
someRandomValue = RandomTask.PickAny(lsTest, 3);Console.WriteLine(string.Join(",", someRandomValue)); - 想按某个概率返回bool值,可以这么写
bool is30Per = RandomTask.PickBoolByProp(0.3); Console.WriteLine(is30Per);
- 最复杂的,一个list中有a,b两个数据,a按照70%概率返回而b按30%返回,就这样写
Dictionary
lsTestAB = new Dictionary { { "A",0.7 }, { "B",0.3} }; string aOrb = RandomTask.PickOneByProb(lsTestAB); Console.WriteLine(aOrb); - 源码
public static class RandomTask { private static readonly Random _random = new Random(); public static int Next() { lock (_random) { return _random.Next(); } } public static int Next(int max) { lock (_random) { return _random.Next(max); } } public static int Next(int min, int max) { lock (_random) { return _random.Next(min, max); } } ///
/// 按概率获取 /// /// ///public static bool PickBoolByProp(double trueProp = 1) { if (trueProp > 1) { trueProp = 1; } if (trueProp < 0) { trueProp = 0; } Dictionary wt = new Dictionary { { true , trueProp }, { false , 1 - trueProp } }; return wt.PickOneByProb(); } /// /// 按指定概率获取随机结果 /// /// a 0.8 b 0.1 c 0.1 ///随机结果 [a,b,c] public static T PickOneByProb(this Dictionary sourceDic) { if (sourceDic == null || !sourceDic.Any()) { return default(T); } int seed = (int)(10 / (sourceDic.Values.Where(c => c > 0).Min())); int maxValue = sourceDic.Values.Aggregate(0, (current, d) => current + (int)(seed * d)); int rNum = Next(maxValue); int tem = 0; foreach (KeyValuePair item in sourceDic) { tem += (int)(item.Value * seed); if (tem > rNum) { return item.Key; } } return default(T); } /// /// 随机从List中获取一项 /// ////// /// public static T PickOne (this List source) { if (source == null || !source.Any()) { return default(T); } return source[Next(source.Count)]; } /// /// /// ////// /// /// public static List PickAny (this List source, int c) { if (source == null || !source.Any()) { return default(List ); } if (source.Count <= c) { return source; } List ls = new List (); for (int i = 0; i < c; i++) { var t = source.PickOne(); if (!ls.Contains(t)) { ls.Add(t); } } return ls; } } - 大家试试吧,真的挺好用的