0

So I have a list of fruit objects in List<Fruit> AllFruits (contains about 60 or so fruit objects) and I also have an empty list of length 3 to house a selection of three fruits List<Fruit> FruitSelection.

This is part of a quiz like game, so on each round, the positions of the fruits need to be different (randomised).

In C#, how can I select a random fruit from AllFruits then place that in a random position in FruitSelection and then do the same for another two fruits, and ensure that they are not duplicates and placed in at a position not already taken within FruitSelection?

PS. A Fruit has a unique Name property.

halfer
  • 19,824
  • 17
  • 99
  • 186
J86
  • 14,345
  • 47
  • 130
  • 228
  • 4
    I am not sure I am following, hence the comment, but couldn't you shuffle the collection and select the top 3? – npinti Jul 07 '15 at 12:06
  • 4
    What do you gain by putting the fruit at a random position in `FruitSelection`? Why not just fill it with randomly selected fruits until the selection is full? – Corak Jul 07 '15 at 12:07
  • I thought for extra shuffling? having read your comment now, you're right it is silly! :( – J86 Jul 07 '15 at 12:08
  • One random suffices. In fact, depending on the kind of random, you could actually loose randomness by consecutive randomization. – Corak Jul 07 '15 at 12:09
  • What clean way would you do this whilst ensuring the randomness does not duplicate? – J86 Jul 07 '15 at 12:10
  • 1
    1. have all elements you want to select from in one list. 2. randomly select a valid index in that list. 3. *remove* the item at that index from the list (and put it somewhere else). 4. repeat 2. and 3. until you removed as many items as you want (or ran out of items to select). -- Your `AllFruit` is already basically what you need for 1., but maybe you want to copy the list each round `List copy = new List(AllFruits);` and use the copy for removing. And the "somewhere else" is your `FruitSelection`. – Corak Jul 07 '15 at 12:16
  • Copy the list, if required. Then use Shuffle from: http://stackoverflow.com/questions/273313/randomize-a-listt-in-c-sharp – TTT Jul 07 '15 at 12:27

3 Answers3

4

Use the .net Random class. You can use it as a param for OrderBy in Linq. So here is some code (use LinqPad):

var fruits = new List<string> { "apple", "orange", "mango" };
var r = new Random();
var newOrderFruits = fruits.OrderBy(x => r.Next()).ToList();
newOrderFruits.Dump();

You see I am using just a list of three strings but you can substitute your list of AllFruits for my fruits string list and get a different order each time.

Please remember not to use a new instance of Random each time!

john-g
  • 874
  • 6
  • 14
  • 1
    `List FruitSelection = AllFruits.OrderBy(x => r.Next()).Take(3).ToList();` – Corak Jul 07 '15 at 12:23
  • upvote for "not to use a new instance of Random each time!" and not using unnecessary loops. – Corak Jul 07 '15 at 12:31
  • `Dump()` is used in [LinqPad](https://www.linqpad.net/) to quickly display the contents of an object. – Corak Jul 07 '15 at 12:48
  • Sorry my trailing parenthesis (use LinqPad) was not very clear. apologies, I just use linqpad to test little snippets like this. Invaluable tool! Next time I will add a link to their site! [link](http://www.linqpad.net/download.aspx) – john-g Jul 08 '15 at 13:34
3

Just add random elements to your list like this:

Random rand = new Random();
List<Fruit> FruitSelection = new List<Fruit>();

for(; FruitSelection.Count < 3;) 
{
    Fruit r = AllFruits[rand.Next(0, AllFruits.Count)];
    if(!FruitSelection.Contains(r)) FruitSelection.Add(r);
}
Fabjan
  • 13,506
  • 4
  • 25
  • 52
1

Order all fruits with a random number and Take the 3 firsts.

var rand = new Random();
var FruitSelection = AllFruits.OrderBy(u => r.Next()).Take(3).ToList();
Menelaos Vergis
  • 3,715
  • 5
  • 30
  • 46