web-dev-qa-db-ja.com

数字を月の名前に変換するswitch caseブロックを短縮する方法は?

これをより少ない行で書く方法はありますが、それでも簡単に読むことができますか?

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;
}
110
Leon Gaban

配列を定義してから、インデックスで取得します。

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

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

配列をまったく使用しないのはどうですか:)

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から

81
vidriduch

これを試して:

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の回答を参照してください|| ''

26
Jaco

注意してください!

すぐにアラームベルをトリガーするのは最初の行です:_var month = '';_-なぜこの変数はnullundefinedではなく空の文字列に初期化されるのですか?それはただの習慣またはコピー/貼り付けされたコードであったかもしれませんが、あなたが確かにそれを知らない限り、コードをリファクタリングしているときにそれを無視することは安全ではありません。

月の名前の配列を使用してコードを_var month = months[mm-1];_に変更すると、動作が変更されます。範囲外の数値または非数値の場合、monthundefined。あなたはこれが大丈夫であることを知っているかもしれませんが、これが悪いだろう多くの状況があります。

たとえば、あなたのswitchが関数monthToName(mm)にあり、誰かがあなたの関数を次のように呼び出しているとしましょう:

_var monthName = monthToName(mm);

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

配列を使用して_monthName[mm-1]_を返すように変更すると、呼び出し元のコードは意図したとおりに機能しなくなり、警告を表示することになっているときにundefined値を送信します。これがgoodコードであると言っているわけではありませんが、コードがどのように使用されているかを正確に知っていない限り、推測することはできません。

または、元の初期化があった可能性があります。行のさらに下のコードは、monthが常に文字列であり、_month.length_のようなことを想定しているためです。呼び出し元のスクリプトを完全に終了させる可能性があります。

あなたがdoコンテキスト全体を知っている場合-例えばそれはすべてあなた自身のコードであり、誰もそれを使用することはありません、andあなたは将来自分が変更を加えたことを忘れないでください-このような振る舞いを変更しても安全かもしれませんが、実生活では防御的なプログラミングや振る舞いを徹底的に文書化する方がはるかに良いというこの種の仮定から多くのバグが発生します。

Wasmooの答え 正しい(編集:受け入れられたものを含む他の多くの答えも修正されました) -_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
}
_
19
CupawnTae

完全を期すために、現在の回答を補足したいと思います。基本的に、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 '';
}

繰り返しますが、ルックアップテーブルまたは日付関数の使用は、より簡潔で主観的にbetterです。

17
Gerard

配列を使用してそれを行うことができます:

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

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

1つの変数のみを使用し、mmが範囲外の場合にデフォルト値''を適用する別のオプションがあります。

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

条件演算子を使用して、スイッチではなく式として記述できます。

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に値を割り当てることであることは明らかです。

9
Guffa

構築 Cupawn Tae's answer previous前に短縮します:

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

あるいは、はい、私は感謝します、読みにくいです:

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

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

私は元の質問にできるだけ近づけるようにします。つまり、1から12の数字を1つの特別な場合だけでなく月名に変換しますが、無効な引数の場合は以前に追加したものを使用してundefinedを返します他の回答に対する批判と内容。 (exactマッチングが必要な場合、undefinedから''への変更は簡単です。)

4
Dirk
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]
}
4
Laxmikant Dange

wasmoo の解決策に行きますが、このように調整します:

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

実際にはまったく同じコードですが、インデントが異なるため、IMOにより読みやすくなります。

0
John Slegers