Как сократить блок блокировки коммутатора, преобразуя число в месяц?

Есть ли способ записать это на меньшее количество строк, но все же легко читается?

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;
}

Ответ 1

Определить массив, затем получить по индексу.

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

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

Ответ 2

как вообще не использовать массив:)

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" }));

в соответствии с этим ответом Получить имя месяца из Даты от David Storey

Ответ 3

Попробуйте следующее:

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

Обратите внимание, что mm может быть целым числом или строкой, и оно все равно будет работать.

Если вы хотите, чтобы несуществующие ключи привели к пустой строке '' (вместо undefined), добавьте следующую строку:

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

JSFiddle.

Ответ 4

Вместо этого вы можете создать массив и найти имя месяца:

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


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

См. ответ от @CupawnTae для рационального кода || ''

Ответ 5

Будьте осторожны!

Вещь, которая должна немедленно вызвать сигнальные колокола, - это первая строка: var month = ''; - почему эта переменная инициализируется пустой строкой, а не null или undefined? Это может быть просто привычка или копировать/вставлять код, но если вы не знаете, что это точно, небезопасно игнорировать его при рефакторинге кода.

Если вы используете массив имен месяцев и меняете свой код на var month = months[mm-1];, вы меняете поведение, потому что теперь для чисел вне диапазона или нечисловых значений month будет undefined. Вы можете знать, что это нормально, но есть много ситуаций, когда это было бы плохо.

Например, предположим, что ваш switch находится в функции monthToName(mm), и кто-то вызывает вашу функцию следующим образом:

var monthName = monthToName(mm);

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

Теперь, если вы перейдете на использование массива и вернетесь monthName[mm-1], вызывающий код больше не будет функционировать так, как предполагалось, и он будет отправлять значения undefined, когда он должен отображать предупреждение. Я не говорю, что это хороший код, но если вы точно не знаете, как используется код, вы не можете делать предположения.

Или, может быть, исходная инициализация была там, потому что какой-то код далее по строке предполагает, что month всегда будет строкой и что-то вроде month.length - это приведет к тому, что исключение будет выбрано за неверные месяцы и потенциально убить вызов script полностью.

Если вы знаете весь контекст - например, это все ваш собственный код, и никто другой никогда не будет использовать его, и вы доверяете себе, не забывайте, что вы сделали изменение когда-нибудь в будущем - может быть безопасно изменить такое поведение, как это, но soooo многие ошибки возникают из такое предположение, что в реальной жизни вам намного лучше защищать и/или документировать поведение.

Ответ Wasmoo исправляет (EDIT: теперь исправлены и другие ответы, в том числе принятые) - вы можете использовать months[mm-1] || '' или если вы предпочли бы сделать это более очевидным с первого взгляда, что происходит, что-то вроде:

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

var month;

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

Ответ 6

Для полноты я хотел бы дополнить текущие ответы. В принципе, вы можете опустить ключевое слово break и напрямую вернуть соответствующее значение. Эта тактика полезна, если значение не может быть сохранено в предварительно вычисленной справочной таблице.

function foo(mm) {
    switch(mm) {
        case '1':  return 'January';
        case '2':  return 'February';
        case '3':  return 'March';
        case '4':  return 'April';
        // [...]
        case '12': return 'December';
    }
    return '';
}

Еще раз, используя справочную таблицу или функции даты, более лаконично и субъективно лучше.

Ответ 7

Вы можете сделать это с помощью массива:

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

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

Ответ 8

Здесь другой параметр, который использует только одну переменную и по-прежнему применяет значение по умолчанию '', когда mm находится вне диапазона.

var month = ['January', 'February', 'March',
             'April', 'May', 'June', 'July',
             'August', 'September', 'October',
             'November', 'December'
            ][mm-1] || '';

Ответ 9

Вы можете записать его как выражение вместо коммутатора, используя условные операторы:

var month =
  mm == 1 ? 'January' :
  mm == 2 ? 'February' :
  mm == 3 ? 'March' :
  mm == 4 ? 'April' :
  mm == 5 ? 'May' :
  mm == 6 ? 'June' :
  mm == 7 ? 'July' :
  mm == 8 ? 'August' :
  mm == 9 ? 'September' :
  mm == 10 ? 'October' :
  mm == 11 ? 'November' :
  mm == 12 ? 'December' :
  '';

Если вы еще не видели закодированных условных операторов, прежде чем это может показаться трудным для чтения вначале. Запись его в виде выражения делает один аспект еще более простым, чем исходный код; ясно, что целью кода является присвоение переменной переменной month.

Ответ 10

Основываясь на ответа Cupawn Tae, я бы сократил его до:

var months = ['January', 'February', ...];
var month = (mm >= 1 && mm <= 12) ? months[mm - 1] : '';

В качестве альтернативы, да, я ценю, менее читаем:

var month = months[mm - 1] || ''; // as mentioned further up

Ответ 11

var getMonth=function(month){
   //Return string to number.
    var strMonth = ['January', 'February', 'March',
             'April', 'May', 'June', 'July',
             'August', 'September', 'October',
             'November', 'December'
            ];
    //return number to string.
    var intMonth={'January':1, 'February':2, 'March':3,
             'April':4, 'May':5, 'June':6, 'July':7,
             'August':8, 'September':9, 'October':10,
             'November':11, 'December':12
            };
    //Check type and return 
    return (typeof month === "number")?strMonth[month-1]:intMonth[month]
}

Ответ 12

Как и @vidriduch, я хотел бы подчеркнуть важность i20y ( "интернационализма" ) кода в сегодняшнем контексте и предложить следующее сжатое и надежное решение вместе с унитарным тестом.

function num2month(month, locale) {
    if (month != Math.floor(month) || month < 1 || month > 12)
        return undefined;
    var objDate = new Date(Math.floor(month) + "/1/1970");
    return objDate.toLocaleString(locale, {month: "long"});
}

/* Test/demo */
for (mm = 1; mm <= 12; mm++)
    document.writeln(num2month(mm, "en") + " " +
                     num2month(mm, "ar-lb") + "<br/>");
document.writeln(num2month("x", "en") + "<br/>");
document.writeln(num2month(.1, "en") + "<br/>");
document.writeln(num2month(12.5, "en" + "<br/>"));

Ответ 13

Я бы выбрал решение wasmoo, но настроил его следующим образом:

var month = [
    'January',
    'February',
    'March',
    'April',
    'May',
    'June',
    'July',
    'August',
    'September',
    'October',
    'November',
    'December'
][mm-1] || '';

Это тот же самый код, действительно, но по-разному с отступом, который IMO делает его более читаемым.