27

I am creating a little quiz console application. I have made a list with 3 questions in it. How can I let the program randomly select a question and print it out int the console?

I have tried some different codes but can't seem the get it working for some reason. This is the last code I tried, which I got from another user from this site, but I get the errors:

The name 'string' does not exist in the current context.

"Since Quiz.Questions.main() returns void, a return keyword must not be followed by an object expression".

Here is the last piece of code which I tried:

class Questions
{
    public static void main()
    {
        var questions = new List<string>{
            "question1",
            "question2",
            "question3"};
        int index = Random.Next(strings.Count);
        questions.RemoveAt(index);
        return questions;

    }

}

Thank you all for your responses. I have fixed my problem by creating an array instead of an List. This is my code now :

class Questions
{
    public static void main()
    {
        string[] questions = new string[3];
        questions[0] = "question1";
        questions[1] = "question2";
        questions[2] = "question3";
        Random rnd = new Random();
        Console.WriteLine(questions[rnd.Next(0,2)]);
    }
}
4
  • How do you call your method? As its currently a void-type you have to leave out the return-value questions Commented Oct 11, 2013 at 12:46
  • 3
    duplicate => stackoverflow.com/questions/2019417/access-random-item-in-list Commented Oct 11, 2013 at 12:46
  • 1
    var randomQuestion = questions[new Random().Next(questions.Count)]; Be sure first that the list is not null Commented Oct 11, 2013 at 12:48
  • Possible duplicate of Access random item in list Commented Apr 30, 2018 at 6:57

8 Answers 8

29

Are you sure that you want to remove a question and return the rest of the questions? Should you not only select one? Somthing like this :

public static void main()
{
    var random = new Random();
    var questions = new List<string>{
        "question1",
        "question2",
        "question3"};
    int index = random.Next(questions.Count);
    Console.WriteLine(questions[index]);
}
Sign up to request clarification or add additional context in comments.

Comments

7

You need a System.Console.WriteLine statment.

class Questions
{
    public static void main()
    {
        var questions = new List<string>{
            "question1",
            "question2",
            "question3"};
        int index = Random.Next(questions.Count);
        System.Console.WriteLine(questions[index]);

    }
}

3 Comments

Also strings.Count should be replaced by questions.Count and Random.Next(...) by new Random().Next(...).
Thanks Alexey. Corrected.
@AlexeyMitev: new Random().Next has the pitfall that it will not create different numbers if it's called repeatedly at short intervals.
6

For other searchers benefit: If you want a depleting list so you ensure you use all items in a random fashion then do this:

//use the current time to seed random so it's different every time we run it
Random rand = new Random(DateTime.Now.ToString().GetHashCode());
var list = new List<string>{ "item1", "item2", "item3"};

//keep extracting from the list until it's depleted
while (list.Count > 0) {
    int index = rand.Next(0, list.Count);
    Console.WriteLine("Rand Item: " + list[index]);
    list.RemoveAt(index);
}

1 Comment

Note: the call to rand.Next should have list.Count as the second argument rather than list.Count - 1 as suggested in this suggested edit as the second argument to Random.Next(int, int) is exclusive. The suggested edit should be rejected.
3

Try something like this

public static void main()
{
    var questions = new List<string>{
        "question1",
        "question2",
        "question3"};
    Random rnd = new Random();
    int index = rnd.Next(questions.Count)
    string question  = questions[index];
    questions.RemoveAt(index); // Are you sure you neex to remove?

    System.Console.WriteLine(question);
}

There is a typo in where you are using string instead of questions. Also, Random object needs to be initalised.

Comments

2

Something like this could be what you want:

private Random rng;
T PickRandom<T>(List<T> list)
{
    return list[rng.NextInt(list.Count)];
}

You can call it on your list to get a random element from it.

1 Comment

I think that Random.NextInt() do not exists in c# (it does on Java). If I am correct, the code should be rng.Next(list.Count) instead of rng.NextInt(list.Count).
2

>= .NET 8

With .NET 8 (which is currently still in preview) we get the GetItems<T>() method that lets you choose a specified number of items from an Array<T> or Span<T> i. e. it would also allow you to easily select 2 or more questions. The method returns an array (also there are other overrides) of the choices made.

var questions = new List<string>
{
    "question1",
    "question2",
    "question3"
};
var numberOfQuestionsToSelectRandomly = 1;
var randomQuestion = Random.Shared.GetItems<string>(CollectionsMarshal.AsSpan(questions), numberOfQuestionsToSelectRandomly);
Console.WriteLine(randomQuestion[0]);

I am using CollectionsMarshal.AsSpan() to create a Span<T> from the List<T>. Using this method you should not add/ remove any items from the list. Alternatively you can turn the list into an array and pass that array to GetItems<T>().

There is Random.GetItems<T>() as well as RandomNumberGenerator.GetItems<T>() which uses a cryptographically secure number generator to choose the items.

Comments

1

"The name 'string' does not exists in current context"

I assume you want

int index = random.Next(questions.Count); // according to the lower-case random see last paragraph

instead of

int index = Random.Next(strings.Count);

Since there is no variable with the name strings and you want to remove one question anyway.

Also, you cannot return something from a void method. So create one that returns the list:

private Random random = new Random();
List<string> GetRemoveQuestion(List<string> questions)
{
        int index = random.Next(questions.Count);
        questions.RemoveAt(index);
        return questions;
}

Edit: last but not least, you cannot use Random.Next. That would presume that there is a static Next method in Random which is not the case. Therefore i have shown above how you create and use an instance. Note that you should not create it i the method itself since it is seeded with the curent time. If you'd call this method very fast you'd get the same "random" value often.

Have a look at msdn at the remarks section for more details.

2 Comments

pretty sure Random does not have a static Next method
@WeylandYutani: Thanks, edited my answer accordingly.
0

You have a couple of minor errors.

You need a reference to a Rand object. You are looking at strings instead of questions. You are removing an element instead of selecting it.

Try this:

void Main()
{
    Random rand = new Random();
    var questions = new List<string>{
        "question1",
        "question2",
        "question3"};
    int index = rand.Next(questions.Count);
    return questions[index];
    // If you want to use Linq then
    // return questions.Skip(index).Take(1);
}

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.