从两个List<>生成随机数。

时间:2015-12-29 14:17:33

标签: c# linq

我想从两个列表中生成随机数。我想创建一个函数,我从两个列表中传递多少随机数。

List<int> integers = new List<int>() { 54, 23, 76, 123, 93, 7, 3489 };
List<int> value2 = new List<int>() { 1, 3, 4, 6, 8, 17, 40 };

我想要我的结果= List<int> result = {54,40,123,17,3,1,3489,76...etc} 当我再次运行时,结果集将会改变。 目前我正在使用这个返回列表的功能

public static List<int> GenerateRandom(int count)
        {
            // generate count random values.
            HashSet<int> candidates = new HashSet<int>();
            while (candidates.Count < count)
            {
                // May strike a duplicate.
                candidates.Add(random.Next(1,30));
            }

            // load them in to a list.
            List<int> result = new List<int>();
            result.AddRange(candidates);

            // shuffle the results:
            int i = result.Count;
            while (i > 1)
            {
                i--;
                int k = random.Next(i + 1);
                int value = result[k];
                result[k] = result[i];
                result[i] = value;
            }
            return result;
        }

我正在调用函数

 List<int> vals = GenerateRandom(20);

但我想要两个List&lt;&gt;中的随机数。 List<int> integersList<int> value2。那我怎么能这样做呢。

5 个答案:

答案 0 :(得分:3)

您可以这样做:

var result = 
    integers.Concat(value2)
    .OrderBy(x => random.Next())
    .Take(count)
    .ToList();

答案 1 :(得分:0)

您可以编写一个通用函数来为您提供任意数量序列的随机排序,如下所示:

public static IReadOnlyCollection<T> InRandomOrder<T>(Random rng, params IEnumerable<T>[] lists)
{
    return lists
        .SelectMany(x => x)
        .OrderBy(y => rng.Next())
        .ToList();
}

然后,您可以根据需要传递任意数量的列表,并以完全随机的顺序返回内容:

var list1 = new[] {1, 2, 3, 4, 5};
var list2 = new[] {6, 7, 8};
var list3 = new[] {9, 0};

Random rng = new Random();

for (int i = 0; i < 10; ++i)
{
    var randomisedFirst5 = InRandomOrder(rng, list1, list2, list3).Take(5);
    Console.WriteLine(string.Join(", ", randomisedFirst5));
}

您可以使用的效率较低的方法可以避免使用Random的实例,但您只能将其用于短列表或您真正不关心性能的情况。它使用Guid.NewGuid()生成随机数:

    public static IReadOnlyCollection<T> InRandomOrder<T>(params IEnumerable<T>[] lists)
    {
        return lists
            .SelectMany(x => x)
            .OrderBy(y => Guid.NewGuid())
            .ToList();
    }

即使是更有效的方法也不是最快的。更快的方法是使用油藏采样来获取您想要的前N个项目,并将它们放入使用Knuth进行洗牌的数组中。这会使代码变得更快,代价是更复杂的代码 - 这意味着只有在真正需要的情况下才能快速完成。

答案 2 :(得分:0)

如果你想要的是随机选择列表A或B中存在的数字,你可以这样做:

    List<int> integers = new List<int>() { 54, 23, 76, 123, 93, 7, 3489 };
    List<int> value2 = new List<int>() { 1, 3, 4, 6, 8, 17, 40 };

    List<int> allInOne = new List<int>(integers.Concat(value2));
    Random r = new Random(DateTime.Now.Millisecond);


    /********************************
        For demonstration purposes
    ********************************/
    for(int i = 0; i < 5; i++)
    {
        var randomListIndex = r.Next(0, allInOne.Count - 1);
        Console.WriteLine(allInOne[randomListIndex]);
    }

答案 3 :(得分:0)

使用KeyValuePair

        static void Main(string[] args)
        {
            List<KeyValuePair<int, int>> results = GenerateRandom(100);
        }
        static List<int> integers = new List<int>() { 54, 23, 76, 123, 93, 7, 3489 };
        static List<int> value2 = new List<int>() { 1, 3, 4, 6, 8, 17, 40 };
        static Random random = new Random();
        public static List<KeyValuePair<int,int>> GenerateRandom(int count)
        {
            List<KeyValuePair<int,int>> result = new List<KeyValuePair<int,int>>();

            for(int i = 0; i < count; i++)
            {
                int firstValue = integers[random.Next(0, integers.Count - 1)];
                int seconValue = value2[random.Next(0, value2.Count - 1)];
                result.Add(new KeyValuePair<int,int>(firstValue,seconValue));
            }

            return result;
        }​

答案 4 :(得分:0)

我实际上制作了一个库来处理这些东西:Underscore.cs

这是一个非常容易安装的nuget包,随机播放或随机抽取两个列表的代码是:

        var ls1 = GenerateRandom(10);
        var ls2 = GenerateRandom(20);

        var mixer = ls1.Concat(ls2).ToList();

        //if you want all of the items shuffled use shuffle
        var result = _.List.Shuffle(mixer);

        //or if you want a subset randomly sorted use sample
        result = _.List.Sample(mixer);