Reputation: 31
I have list of 70 question numbers out of which I want to select 50 random and unique questions. How can I do this?
Here is what I have so far:
static Random random = new Random();
static void Main(string[] args)
{
List<int> questionNumbers = new List<int>();
for (int i = 0; i < 70; i++)
{
questionNumbers.Add(i);
}
List<int> randomAndUniqueNumbers = GenerateRandom(50);
}
public static List<int> GenerateRandom(int count)
{
// ????
}
Upvotes: 3
Views: 733
Reputation: 117175
Try this:
List<int> randomAndUniqueNumbers =
Enumerable
.Range(0, 70)
.OrderBy(x => random.Next())
.Take(50)
.ToList();
Upvotes: 1
Reputation: 1073
Without getting into theory, DO NOT do any of the earlier answers. You should be implementing a Fisher-Yates Shuffle and then take the first 50 elements of the shuffled list.
To save you some time I've put an implementation below. The Shuffle function is generic so if later you decide to actually shuffle questions (e.g. a List<Question>
instead of numbers it will still work for you:
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main(string[] args)
{
List<int> numbers = Enumerable.Range(1, 70).ToList();
Shuffle(numbers);
foreach (int number in numbers.Take(50))
{
Console.WriteLine(number);
}
Console.ReadLine();
}
static void Shuffle<T>(IList<T> items)
{
Random rand = new Random();
for (int i = items.Count - 1; i > 0 ; i--)
{
int j = rand.Next(i + 1); // Returns a non-negative random integer that is less than the specified maximum - MSDN
T temp = items[i];
items[i] = items[j];
items[j] = temp;
}
}
}
Upvotes: -1
Reputation: 186833
Well, just remove the taken question (or its index) from the list:
static Random random = new Random();
private static IEnumerable<int> GenerateRandom(int takeCount, int questionCount) {
List<int> numbers = Enumerable
.Range(0, questionCount)
.ToList();
for (int i = 0; i < takeCount; ++i) {
int index = random.Next(numbers.Count);
yield return numbers[index];
numbers.RemoveAt(index);
}
}
static void Main(string[] args) {
List<int> randomAndUniqueNumbers = GenerateRandom(50, 70).ToList();
}
Upvotes: 0
Reputation: 4355
static Random random = new Random();
static List<int> questionNumbers = new List<int>();
static void Main(string[] args)
{
for (int i = 0; i < 70; i++)
{
questionNumbers.Add(i);
}
List<int> randomAndUniqueNumbers = GenerateRandom(50);
}
//This function doesn't require index in questionNumbers
//to be from 0 and continuous
public static List<int> GenerateRandom(int count)
{
List<int> lst = new List<int>();
List<int> q = questionNumbers.ToList();
for (int i = 0; i < count; i++)
{
int index = random.Next(0, q.Count);
lst.Add(q[index]);
q.RemoveAt(index);
}
return lst.OrderBy(x => x).ToList();
}
Upvotes: 0
Reputation: 34433
Try this
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication61
{
class Program
{
static void Main(string[] args)
{
}
}
public class Question
{
private static Random rand = new Random();
public static List<Question> questions { get; set; }
public string question { get; set; }
public int randomNumber { get; set; }
public void Shuffle()
{
foreach(Question question in questions)
{
question.randomNumber = rand.Next();
}
questions = questions.OrderBy(x => x.randomNumber);
}
}
}
Upvotes: -1
Reputation: 6766
Try using extension methods of Linq.
class Program
{
static void Main(string[] args)
{
List<int> questionNumbers = new List<int>();
for (int i = 0; i < 70; i++)
{
questionNumbers.Add(i);
}
List<int> randomAndUniqueNumbers = questionNumbers.GenerateRandom(50);
}
}
public static class Extensions
{
static Random random = new Random();
public static List<T> GenerateRandom<T>(this List<T> collection, int count)
{
return collection.OrderBy(d => random.Next()).Take(count).ToList();
}
}
Dot net fiddle is here
Upvotes: 4
Reputation: 1383
This should do it. You might want to bound the random number by putting in a min and max into random.Next(min, max)
public static List<int> GenerateRandom(int count)
{
var result = new HashSet<int>();
while (result.Count < 50)
{
result.Add(random.Next());
}
return result.ToList();
}
Upvotes: -3