再来写一个随机数解决方案,对Random再来一次封装
本文提供对Random的封装,简化并扩展了其功能
- 获取随机数,确保同时调用不会重复
//new Random().Next(5); RandomTask.Next(5);
- 从一个列表中,随机获取其中某个值
List<string> lsTest = new List<string> { "1","2","3","4","5" }; string randomValue = RandomTask.PickOne(lsTest); Console.WriteLine(randomValue);
- 从一个列表中,随机获取其中多个值
List<string> 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<string, double> lsTestAB = new Dictionary<string, double> { {"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); } } /// <summary> /// 按概率获取 /// </summary> /// <param name="trueProp"></param> /// <returns></returns> public static bool PickBoolByProp(double trueProp = 1) { if (trueProp > 1) { trueProp = 1; } if (trueProp < 0) { trueProp = 0; } Dictionary<bool, double> wt = new Dictionary<bool, double> { { true , trueProp }, { false , 1 - trueProp } }; return wt.PickOneByProb(); } /// <summary> /// 按指定概率获取随机结果 /// </summary> /// <param name="sourceDic">a 0.8 b 0.1 c 0.1</param> /// <returns>随机结果 [a,b,c]</returns> public static T PickOneByProb<T>(this Dictionary<T, double> 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<T, double> item in sourceDic) { tem += (int)(item.Value * seed); if (tem > rNum) { return item.Key; } } return default(T); } /// <summary> /// 随机从List中获取一项 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="source"></param> /// <returns></returns> public static T PickOne<T>(this List<T> source) { if (source == null || !source.Any()) { return default(T); } return source[Next(source.Count)]; } /// <summary> /// /// </summary> /// <typeparam name="T"></typeparam> /// <param name="source"></param> /// <param name="c"></param> /// <returns></returns> public static List<T> PickAny<T>(this List<T> source, int c) { if (source == null || !source.Any()) { return default(List<T>); } if (source.Count <= c) { return source; } List<T> ls = new List<T>(); for (int i = 0; i < c; i++) { var t = source.PickOne(); if (!ls.Contains(t)) { ls.Add(t); } } return ls; } }
- 大家试试吧,真的挺好用的
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· SQL Server 2025 AI相关能力初探
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库