如何缩短将数字转换为月份名称的开关盒块?

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

有没有一种方法可以减少行数,但仍然易于阅读?

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

试试这个:

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

请注意,mm 可以是整数或字符串,它仍然有效。

如果您希望不存在的键生成空字符串 ''(而不是 undefined),则添加此行:

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

JSFiddle.

您可以改为创建一个数组并查找月份名称:

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


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

请参阅@CupawnTae 的回答以了解代码背后的合理性 || ''

定义一个数组,然后通过索引获取。

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

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

您可以使用数组来完成:

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

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

完全不使用数组怎么样:)

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

的回答 Get month name from Date

这是另一个仅使用 1 个变量的选项,当 mm 超出范围时仍应用默认值 ''

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

小心!

应该立即触发警钟的是第一行:var month = ''; - 为什么这个变量被初始化为空字符串,而不是 nullundefined?它可能只是习惯或 copy/pasted 代码,但除非您确定知道,否则在重构代码时忽略它是不安全的。

如果您使用月份名称数组并将代码更改为 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 的操作 - 这将导致抛出异常对于无效的月份,可能会完全终止调用脚本。

如果您确实了解整个上下文 - 例如这都是你自己的代码,没有人会使用它,你相信自己不要忘记你在未来的某个时候做出了改变——改变像这样的行为,但是很多错误都来自这种假设,即在现实生活中你最好进行防御性编程 and/or 彻底记录行为。

正确 (编辑:许多其他答案,包括已接受的答案,现在也已修复) - 您可以使用 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
}

为了完整起见,我想补充一下当前的答案。基本上,您可以省略 break 关键字并直接 return 一个适当的值。如果无法将值存储在预先计算的查找 table.

中,则此策略很有用
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 '';
}

再一次,使用查找 table 或日期函数更加简洁和主观 更好

您可以使用条件运算符将其写成表达式而不是开关:

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.

赋值
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]
}

基于 之前的回答,我将其缩短为:

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

或者,是的,我很欣赏,可读性较差:

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

与@vidriduch 一样,我想强调 i20y ("internationalisability") 代码在当今上下文中的重要性,并建议以下简洁而可靠的解决方案以及单一测试。

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

我尽量贴近原问题,即将数字 1 到 12 转换为月份名称,不仅针对一种特殊情况,而且 return undefined 以防无效论据,使用一些以前添加的批评和其他答案的内容。 (从 undefined'' 的变化是微不足道的,以防需要 精确 匹配。)

我会选择 wasmoo 的解决方案,但要像这样调整它:

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

确实是完全相同的代码,但缩进不同,IMO 使其更具可读性。