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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.