再来写一个随机数解决方案,对Random再来一次封装

时间:2023-11-16 15:32:08

本文提供对Random的封装,简化并扩展了其功能

  • 获取随机数,确保同时调用不会重复
     //new Random().Next(5);
    RandomTask.Next();
  • 从一个列表中,随机获取其中某个值
                List<string> lsTest = new List<string>
    {
    "","","","",""
    };
    string randomValue = RandomTask.PickOne(lsTest);
    Console.WriteLine(randomValue);
  • 从一个列表中,随机获取其中多个值
    List<string> someRandomValue = RandomTask.PickAny(lsTest, );
    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 = )
    {
    if (trueProp > )
    {
    trueProp = ;
    }
    if (trueProp < )
    {
    trueProp = ;
    }
    Dictionary<bool, double> wt = new Dictionary<bool, double>
    {
    { true , trueProp },
    { false , - 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)( / (sourceDic.Values.Where(c => c > ).Min()));
    int maxValue = sourceDic.Values.Aggregate(, (current, d) => current + (int)(seed * d)); int rNum = Next(maxValue);
    int tem = ;
    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 = ; i < c; i++)
    {
    var t = source.PickOne();
    if (!ls.Contains(t))
    {
    ls.Add(t);
    }
    }
    return ls;
    }
    }
  • 大家试试吧,真的挺好用的