How to shorten switch case block converting a number to a month name?

Is there a way to write this on fewer lines, but still easily readable?

var month = '';

switch(mm) {
    case '1':
        month = 'January';
        break;
    case '2':
        month = 'February';
        break;
    case '3':
        month = 'March';
        break;
    case '4':
        month = 'April';
        break;
    case '5':
        month = 'May';
        break;
    case '6':
        month = 'June';
        break;
    case '7':
        month = 'July';
        break;
    case '8':
        month = 'August';
        break;
    case '9':
        month = 'September';
        break;
    case '10':
        month = 'October';
        break;
    case '11':
        month = 'November';
        break;
    case '12':
        month = 'December';
        break;
}

Solution 1:

Define an array, then get by index.

var months = ['January', 'February', ...];

var month = months[mm - 1] || '';

Solution 2:

what about not to use array at all :)

var objDate = new Date("10/11/2009"),
    locale = "en-us",
    month = objDate.toLocaleString(locale, { month: "long" });

console.log(month);

// or if you want the shorter date: (also possible to use "narrow" for "O"
console.log(objDate.toLocaleString(locale, { month: "short" }));

as per this answer Get month name from Date from David Storey

Solution 3:

Try this:

var months = {'1': 'January', '2': 'February'}; //etc
var month = months[mm];

Note that mm can be an integer or a string and it will still work.

If you want non-existing keys to result in empty string '' (instead of undefined), then add this line:

month = (month == undefined) ? '' : month;

JSFiddle.

Solution 4:

You could create an array instead and lookup the month name:

var months = ['January','February','March','April','May','June','July','August','September','October','November','December']


var month = months[mm-1] || '';

See the answer by @CupawnTae for the rational behind the code || ''

Solution 5:

Be careful!

The thing that should immediately trigger alarm bells is the first line: var month = ''; - why is this variable being initialized to an empty string, rather than null or undefined? It may just have been habit or copy/pasted code, but unless you know that for sure, it is not safe to ignore it when you're refactoring code.

If you use an array of month names and change your code to var month = months[mm-1]; you are changing the behaviour, because now for numbers outside the range, or non-numeric values, month will be undefined. You may know that this is ok, but there are many situations where this would be bad.

For example, let's say your switch is in a function monthToName(mm), and someone is calling your function like this:

var monthName = monthToName(mm);

if (monthName === '') {
  alert("Please enter a valid month.");
} else {
  submitMonth(monthName);
}

Now if you change to using an array and returning monthName[mm-1], the calling code will no longer function as intended, and it will submit undefined values when it is supposed to display a warning. I'm not saying this is good code, but unless you know exactly how the code is being used, you can't make assumptions.

Or maybe the original initialization was there because some code further down the line assumes that month will always be a string, and does something like month.length - this will result in an exception being thrown for invalid months and potentially kill the calling script completely.

If you do know the entire context - e.g. it's all your own code, and no-one else is ever going to use it, and you trust yourself not forget you made the change sometime in the future - it may be safe to change the behaviour like this, but soooo many bugs come from this kind of assumption that in real life you're far better off programming defensively and/or documenting the behaviour thoroughly.

Wasmoo's answer gets it right (EDIT: a number of other answers, including the accepted one, have now been fixed too) - you can use months[mm-1] || '' or if you would prefer to make it more obvious at a glance what's happening, something like:

var months = ['January', 'February', ...];

var month;

if (mm >= 1 && m <= 12) {
  month = months[mm - 1];
} else {
  month = ''; // empty string when not a valid month
}