Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using LINQ to generate a random size collection filled with random numbers

Tags:

c#

linq

I'm learning LINQ right now and I'm wondering if there is any way to use it to actually generate a list rather than just querying an already generated list. So I have the following code using for loop to get make a random size list of ints and fill it with random numbers, is there anyway to convert it to LINQ?

var ret = new List<int>();
for (var i = 0; i < _rand.Next(100); i++)
    ret.Add(_rand.Next(10));
like image 532
Sathariel Avatar asked Feb 04 '11 23:02

Sathariel


5 Answers

You could do this:

Random _rand = new Random();
var results = Enumerable.Range(0, _rand.Next(100))
                        .Select(r => _rand.Next(10))
                        .ToList();
like image 96
BrokenGlass Avatar answered Oct 21 '22 08:10

BrokenGlass


You could do it like this:

List<int> result = Enumerable.Range(0, _rand.Next(100))
    .Select(x => _rand.Next(10))
    .ToList();

Using LINQ here will give poorer performance and I'm not sure it improves the readability either. It might be best to do it like this:

int length = _rand.Next(100);
for (var i = 0; i < length; i++)
{
    ret.Add(_rand.Next(10));
}
like image 39
Mark Byers Avatar answered Oct 21 '22 08:10

Mark Byers


I think it's not elegant to first generate a sequence of numbers only to throw it away. These methods deliver random numbers on the spot (you have to pay with verbosity though):

IEnumerable<int> GetRandomSequence(int maxNumber)
{
    var random = new Random();
    while (true)
        yield return random.Next(maxNumber);
}

IEnumerable<int> GetRandomSequence(int maxNumber, int maxCount)
{
    return GetRandomSequence(maxNumber).Take(maxCount);
}

var random = new Random();
var list = GetRandomSequence(100, 10).ToList ();

And I love how I can write the same in F#:

let random = new Random ();
let list = Seq.init (random.Next 10) (fun _ -> random.Next 100)
           |> List.ofSeq;
like image 40
Dan Abramov Avatar answered Oct 21 '22 09:10

Dan Abramov


Btw, I guess in your original solution you aren't getting exactly what you expect, since _rand.Next(100) is evaluated for every loop iteration. So the list length has not uniform distribution in [0; 100)

like image 32
driushkin Avatar answered Sep 22 '22 21:09

driushkin


You can use NBuilder:

var random = new Random();
var list = Builder<int>.CreateListOfSize(random.Next())
                       .WhereAll()
                       .HaveDoneToThem(x => random.Next())
                       .Build();

The advantage of NBuilder is that you can use it not only to easily create large lists of primitives (trivial), but also to easily create large lists of complex types (not so trivial):

var list = Builder<Product>.CreateListOfSize(100)
                           .WhereAll()
                           .HaveDoneToThem(x => x.Name = GetRandomName())
                           .And(x => x.Cost = GetRandomCost())
                           .Build();
like image 25
Daniel T. Avatar answered Oct 21 '22 07:10

Daniel T.