如何缩短将数字转换为月份名称的开关盒块?
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;
您可以改为创建一个数组并查找月份名称:
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 = '';
- 为什么这个变量被初始化为空字符串,而不是 null
或 undefined
?它可能只是习惯或 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 使其更具可读性。
有没有一种方法可以减少行数,但仍然易于阅读?
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;
您可以改为创建一个数组并查找月份名称:
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 = '';
- 为什么这个变量被初始化为空字符串,而不是 null
或 undefined
?它可能只是习惯或 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 使其更具可读性。