0

C# noob here, trying to experiment with different ways of solving a basic problem. I want to pass in an argument to a method and in that method I loop through an array of months. If the argument equals the position of the array, I want to return the string of that array position.

I've tried the following:

class Month
{
    private int month;

    public string strMonth(int month)
    {
        this.month = month;

        string[] months = { " ", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" };

        for (int i = 0; i < months.Length; i++)
        {
            if (month == Array.IndexOf(months, i))
            {
                return months[i];
            }
        }

        return "check fails";
    }
}

And for my driver I'm using

class Program
{
    static void Main(string[] args)
    {
        Month testMonth = new Month();

        Console.WriteLine(testMonth.strMonth(2));

        Console.ReadKey();
    }
}

However, I'm always getting check fails logged in the console. Am I on the right path or has the noobness prevailed and I'm doing this totally wrong? I'm also confused about the block level scoping (I think that's what C# does?). I come from a JS background and I'm used to function level scope. Will adding the return "check fails" always execute even if my check passes?

Dann
  • 117
  • 1
  • 11
  • You're aware that for "January" you will have to insert 0 right? – HelloWorld Feb 25 '15 at 17:46
  • Yes, I'm aware of that. I have an empty string as [0] to cheat the check. Thank you for pointing that out though. That has nothing to do with my problem though. – Dann Feb 25 '15 at 17:46

6 Answers6

1

A more cleaner approach would be to use a dictionary. Something like:

class Month
{
    public string strMonth(int month)
    {
        var months = new Dictionary<int, string>
        {
            {1, "Jan"},
            {2, "Feb"},
            {3, "March"},
            {4, "April"},
            {5, "May"},
            {6, "June"},
            {7, "July"},
            {8, "Aug"},
            {9, "Sept"},
            {10, "Oct"},
            {11, "Nov"},
            {12, "Dec"}
        };

        var monthString = "check fails";
        if (months.ContainsKey(month))
        {
            monthString = months[month];
        }
        return monthString;
    }
}
d.moncada
  • 16,900
  • 5
  • 53
  • 82
  • you're welcome. it also reduces complexity as you do not have to iterate through the array – d.moncada Feb 25 '15 at 18:09
  • If the problem is really about getting a month name from a number then http://stackoverflow.com/questions/3184121/get-month-name-from-month-number may be of interest and has the advantage of working for different cultures, etc. too. – Chris Feb 25 '15 at 18:46
  • @Chris it's really not, I just wanted to experiment with matching an int argument to a position in an array and this seemed like a good use case. – Dann Feb 25 '15 at 23:23
  • @Dann: I did suspect that but when you accepted an answer that wasn't about getting things out of an array by their position I became uncertain. ie the accepted answer seems to save the "get month by integer" rather than the "get value from an existing array" part of your question and doesn't even address why your code doesn't work. As long as your good though then its all good. :) – Chris Feb 26 '15 at 10:14
  • @Chris I see a couple of other answers that seem to address why my code doesn't work and more along the lines of my original question, but I like this solution the most. I've never used a dictionary before and, to me, it seems like a good alternative in this case :) – Dann Feb 26 '15 at 16:45
0

This should do it and prevent illegal indexes from trying to access the array and send an exception message.

class Month
{
    private int month;

    public string strMonth(int month)
    {
        this.month = month;

        string[] months = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" };
        if (month <= months.Length && month > 0)
            return months[i-1];
    }
    return "check fails";
}
HelloWorld
  • 1,128
  • 1
  • 7
  • 14
0

Reading the docs for Array.IndexOf will make it clear what is wrong:

Searches for the specified object and returns the index of its first occurrence in a one-dimensional array.

https://msdn.microsoft.com/en-us/library/7eddebat(v=vs.110).aspx

So what you are doing is searching for the int 2 in the array and it is not finding it so returning -1 which of course never equals your input.

The best way of doing what you want is simply return months[month].

Chris
  • 27,210
  • 6
  • 71
  • 92
0

If you simply need a month name you could do that with DateTimeFormatInfo.GetMonthName()

for example public string strMonth(int month) { return System.Globalization.CultureInfo .CurrentCulture.DateTimeFormat.GetMonthName(month); }

Tadas Šukys
  • 4,140
  • 4
  • 27
  • 32
0

You have a lot of unnecessary code for turning an index into an array element. You are really overthinking this problem.

public string strMonth(int index)
{
    string[] months = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" };
    return months[index]; //0-index array (Jan = 0)
}

If you are trying to turn a 1-based index (Jan = 1) into a string, just subtract 1 from the index with return months[index - 1];. Then you avoid having the blank string as a possible result.

And as always, consider where you want to handle possible ArrayIndex Exceptions.
If you want to validate the index inside this method (instead of letting the Exception bubble up to the calling method), you can add this check:

public string strMonth(int index)
{
    if (index < 0|| index > 11) //or 1, 12 for the 1-indexed version
         return "Failed.";

    string[] months = { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" };
    return months[index]; //0-indexed array (Jan = 0)
}
ryanyuyu
  • 6,366
  • 10
  • 48
  • 53
0
using System;

namespace Test
{
    class MainClass
    {
        public static void Main (string[] args)
        {
            string[] data = new string[] { "a", "b", "c", "d", "e", "f" };

            int input = Convert.ToInt32 (Console.ReadLine ());
            try {
                Console.WriteLine (data [input]);
            } catch (IndexOutOfRangeException) {
                Console.WriteLine ("Invalid input.");
            }
        }
    }
}