Mark
Mark

Reputation: 77

C# foreach iterator isn't traversing my List in order

I'm new to C# and I was wondering if someone could explain why the list doesn't print out in order in the foreach loop? I also noticed that the .ToList() changes the order of the cards if you look at them in the watch window. Why would that be?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CardShuffle
{
    class Program
    {
        static void Main(string[] args)
        {
            var r = new Random();
            var cards = Enumerable.Range(0, 51);
            var shuffledcards = cards.OrderBy(a => r.Next(1000));
            var aList = shuffledcards.ToList();

            foreach( int card in aList)
            {
                Console.WriteLine("Card {0} is {1}.", card, aList[card]);
            }
            Console.WriteLine();

            for (int card = 0; card < aList.Count; ++card )
            {
                Console.WriteLine("Card {0} is {1}.", card, aList[card]);
            }
            Console.ReadKey();
        }
    }
}

Upvotes: 0

Views: 286

Answers (5)

Muhammad Umar
Muhammad Umar

Reputation: 3781

Your foreach loop is incorrect. Try this

int counter = 0;
foreach( int card in aList)
{
    Console.WriteLine("Card {0} is {1}", counter , card);
    counter++;
}

Upvotes: 0

MarcinJuraszek
MarcinJuraszek

Reputation: 125650

Your foreach loop logic is wrong. What you're doing there is you're taking items from aList collection, and then use them as an index to take another element in aList collection. That's why you get that kind of output.

To get the same output from your foreach as from your for loop, try that:

foreach (var item in aList.Select((c, i) => new { card = c, index = i }))
{
    Console.WriteLine("Card {0} is {1}.", item.index, item.card);
}

Upvotes: 0

mattnedrich
mattnedrich

Reputation: 8062

In the foreach loop you're writing the cards using the values as the index. In the for loop your writing the cards in order based on index.

Upvotes: 0

evanmcdonnal
evanmcdonnal

Reputation: 48114

There's a bug in your foreach;

foreach( int card in aList)
{
    Console.WriteLine("Card {0} is {1}.", card, aList[card]);
}

card is not the index, it's the value itself. So you're printing the value (as the card number) then randomly accessing whatever is at that index and displaying it as the value. You should be using a counter to display the card number and using card to replace {1}.

int i = 0;
foreach( int card in aList)
{
     Console.WriteLine("Card {0} is {1}.", i, card);
     i++;
}

Upvotes: 4

inside
inside

Reputation: 3177

Let's say you have

List<int> aList = new List<int>();
aList.Add(1);
aList.Add(5);
aList.Add(10);
aList.Add(20);

and you are trying to do

foreach( int card in aList)
   {
      Console.WriteLine("Card {0} is {1}.", card, aList[card]);
   }

What you are actually doing is trying to access random elements of array, because in the second loop in my case it will access the fifth element of array not the second one, so you need to run for loop if you want the correct result.

Upvotes: 0

Related Questions