0

Is there a way to either iterate through an enum or retrieve its position in the enum list. I have the following example code.

    private static void Main(string[] args)
    {
        DateTime sinceDateTime;
        Counters counter = new Counters();

        // Iterate through time periods
        foreach (TimePeriodsToTest testTimePeriod in Enum.GetValues(typeof(TimePeriodsToTest)))
        {
            // e.g. DateTime lastYear = DateTime.Now.AddDays(-365);
            sinceDateTime = DateTime.Now.AddDays((double)testTimePeriod);
            var fileCount =
                Directory.EnumerateFiles("c:\\Temp\\")
                    .Count(path => File.GetCreationTime(path).Date > sinceDateTime);

            Console.WriteLine("Files since " + -(double)testTimePeriod + " days ago is : " + fileCount);
            // counter.TimePeriodCount[testTimePeriod] = fileCount;
        }
    }

    public enum TimePeriodsToTest
    {
        LastDay = -1,
        LastWeek = -7,
        LastMonth = -28,
        LastYear = -365
    }

    public class Counters
    {
        public int[] TimePeriodCount = new int[4];
    }

    public class Counters2
    {
        public int LastDay;
        public int LastWeek;
        public int LastMonth;
        public int LastYear;
    }

So I want to store the value fileCount into counter.TimePeriodCount[]. If I can get the 'position value' of testTimePeriod, then that would slot quite nicely into the array counter.TimePeriodCount[]. But I haven't been able to find out how to do that yet.

If LastDay, LastWeek, etc were 1, 2, 3, 4 then that wouldn't be a problem, but they aren't and I have a problem!

Alternatively, would there be a way to store fileCount into Counters2.LastDay, Counters2.LastWeek, etc. on subsequent iterations?

Or am I just approaching this the wrong way?

Update The suggestion given by "KuramaYoko" can work by adding a Dictionary to the solution but I found the solution given by Jones6 to be more elegant as it does not require adding a Dictionary. Thanks for your time and effort as I learnt something from both answers :-)

Update2 Now I understand the way AlexD solution should be used, that is also a very good way to solve the problem. Thanks.

Alan
  • 306
  • 2
  • 10
  • possible duplicate of [Using an enum as an array index in C#](http://stackoverflow.com/questions/981776/using-an-enum-as-an-array-index-in-c-sharp) – gibertoni Apr 10 '15 at 20:12
  • 1
    Thanks for the suggestion. I was able to make it to work that way but I had to set up a dictionary to solve the problem. Jones6 answer was shorter and solved the problem more elegantly for me. But thanks for the suggestion as I never thought of using the Dictionary as a possible solution. – Alan Apr 11 '15 at 20:13

2 Answers2

5

You can use Enum.GetValues method to get all enum values. I doubt that the order is guaranteed, so you may want to sort the values.

int[] values = Enum.GetValues(typeof(TimePeriodsToTest))
    .Cast<int>()
    .OrderBy(x => x)
    .ToArray();

for (int k = 0; k < values.Length; k++)
{
    sinceDateTime = DateTime.Now.AddDays(values[k]);
    fileCount = ....
    counter.TimePeriodCount[k] = fileCount;
}

BTW, similarly Enum.GetNames will give you the names.

AlexD
  • 32,156
  • 3
  • 71
  • 65
  • 1
    He wants the index value of the enum item, not the actual value stored in the item. – gibertoni Apr 10 '15 at 20:13
  • Enum.GetValues(typeof(TimePeriodsToTest)) will only get me the values (-1, -7, -28, -365). As I defined enums, I was trying to iterate through them and yet still have the 0, 1, 2, 3 position value of each particular enum value. The most elegant solution for my purpose was the one given by jones6. – Alan Apr 11 '15 at 20:48
  • @Alan Just to be sure. I updated the post. Is this what you meant? – AlexD Apr 11 '15 at 21:27
  • @AlexD Ah ... I didn't realise your solution meant not using the enum types within the loop, but casting the enum values into an array then iterating through that array instead. My thinking was still stuck on using the enum values within the loop. Thanks for the alternative solution. – Alan Apr 12 '15 at 05:08
  • @Alan Alternatively, you could make `TimePeriodCount` a `List` instead of array, and simply add a new item on every step. – AlexD Apr 12 '15 at 09:35
1

You should be able to do this

foreach (var testTimePeriod in Enum.GetValues(typeof(TimePeriodsToTest)).Cast<TimePeriodsToTest>().Select((x, i) => new { Period = x, Index = i}))
{
     counter.TimePeriodCount[testTimePeriod.Index] = fileCount;
}
jones6
  • 704
  • 5
  • 7
  • Thanks. This helped me out the most. I only had to do the minimal amount of code changes. I learn something new every day. Thanks. – Alan Apr 11 '15 at 20:10