c#封装Random随机数

目录

背景

用法

获取随机数,确保同时调用不会重复

从一个列表中,随机获取其中某个值

从一个列表中,随机获取其中多个值

想按某个概率返回bool值,可以这么写

最复杂的,一个list中有a,b两个数据,a按照70%概率返回而b按30%返回,就这样写

完整源码


背景

在项目开发过程中,经常会使用到系统里随机数的功能,顾名思义,就是需要获取一定概率下的结果。

比如需要一个集合中随机抽取其中某个或者某几个元素;又或者需要以一定概率值返回一个bool值(以38%的概率返回True)等;以及需要产生连续的随机数等需求存在一定的普遍性。

用法

获取随机数,确保同时调用不会重复

 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;
        }
    }

​​​​​​

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

deanZZZZZZ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值