숫자를 월 이름으로 변환하는 스위치 케이스 블록을 단축하는 방법은 무엇입니까?


110

적은 수의 줄로 작성하는 방법이 있지만 여전히 쉽게 읽을 수 있습니까?

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

7
IMHO vidriduch의 답변 이 가장 적절합니다. 이것은 아마도 당신의 코드에서 Date 조작이 필요한 유일한 부분은 아닐 것입니다 (당신이 보여준 것은 코딩하기가 특히 쉽습니다). 기존의 테스트 된 Date 라이브러리 사용을 심각하게 고려해야합니다.
coredump

2
나는 자바 스크립트를 모르지만 Python의 사전이나 C ++의 std :: map과 같은 해시 맵이 없습니까?
가면 남자


2
기본 ''을 고려하지 않아 코드의 동작을 변경하는 많은 답변이 정의되지 않은 출력을 초래하며 이는 원본과 다릅니다.
Pieter B

2
입니다 하지 > 중복 질문 :(이 대답은하지만 동일 할 수 완전히 다른 질문을한다.
레온 Gaban

답변:


199

배열을 정의한 다음 인덱스로 가져옵니다.

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

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

23
대신 mm - 1당신도 설정할 수 undefined개월의 번호와 일치 할 배열 인덱스 그래서 첫 번째 값 (인덱스 0)로
Touffy

9
var month = month[(mm -1) % 12]
mpez0 2015

77
@ mpez0 나는 누군가가 아마도 나쁜 데이터를 숨기는 것보다 월 번호 15를 생각 해냈다는 것을 아는 것을 선호한다고 생각합니다
Izkata

21
@Touffy 나는 내가 고착 할 것이라고 생각 mm-1한다 months.length==12.
Teepeemm 2015

48
@Touffy 나는 그것이 취향의 문제가 아니라 영리한 코드피하는 문제라고 주장합니다 . 다른 책을 읽는다고 상상해보세요. 당신 [undefined, 'January', 'February', ...]의 첫 번째 반응은 WTF입니까?! , 이는 ... 일반적으로 좋은 징조 아니다
miraculixx

81

배열을 전혀 사용하지 않는 것은 어떻습니까? :)

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 에서 날짜 에서 월 이름 가져 오기


2
문제의 문제 진술을 감안할 때 귀하의 대답은 실제로 그 문제를 해결하는 것이 아니라 다른 맥락에서 옳을 수있는 다른 해결책입니다. 선택된 답변은 여전히 ​​가장 좋고 가장 효율적입니다.
TechMaze

6
new Date("2009-11-10")형식 만 구문 분석 할 수 있습니다 (이 사양 참조 : ecma-international.org/publications/standards/Ecma-262.htm ). 브라우저가 그렇게 선택하면 다른 날짜 형식 (답변에 포함)이 구문 분석 될 수 있으므로 이식 가능하지 않습니다.
jb.

58

이 시도:

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

참고 mm 정수 또는 문자열이 될 수 있으며, 그것은 여전히 작동합니다.

존재하지 않는 키가 빈 문자열 ''(대신 undefined)이되도록하려면 다음 줄을 추가합니다.

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

JSFiddle .


4
"월"보다 더 큰 데이터 세트에서는이 방법이 아마도 더 효율적일 것입니다.
DGM 2015

3
이것은 사실상 열거 형입니다 (즉, 변경 불가능하게 만듭니다). JavaScript에서 열거 형var months = Object.freeze({'1': 'January', '2': 'February'}); //etc 보기 로 정의 합니까?
Alexander

1
@Alexander 키와 값을 바꾸면 예, 열거 형과 비슷합니다.
하지만하지 래퍼 클래스 해요

26

대신 배열을 만들고 월 이름을 조회 할 수 있습니다.

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


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

코드이면의 합리적인 이유는 @CupawnTae의 답변을 참조하십시오. || ''


오히려 0 인덱스 시작보다 당신은 유지할 수 undefined0var months = [ undefined, 'January','February','March', .....사용됩니다 이런 식으로month = months[mm];
Grijesh 차우

@GrijeshChauhan : '영리한'코드는 피하세요. 다음 사람의 첫 번째 반응은 wtf입니다. 그것은 단지 '-1', 개월이고 길이는 13, wtf ^ 2가 될 것입니다. programmers.stackexchange.com/questions/91854/...
RVDK

19

조심해!

즉시 알람 벨을 트리거해야하는 것은 첫 번째 줄입니다 var month = '';.-이 변수가 null또는 대신 빈 문자열로 초기화되는 이유undefined 무엇입니까? 그것은 단지 습관이거나 복사 / 붙여 넣기 된 코드 일 수 있지만, 확실히 알지 못한다면 코드를 리팩토링 할 때 무시하는 것이 안전하지 않습니다.

월 이름 배열을 사용하고 코드를 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경고를 표시해야 할 때 값 을 제출 합니다. 이것이 좋은 코드 라고 말하는 것은 아니지만 코드가 어떻게 사용되는지 정확히 알지 못하면 가정을 할 수 없습니다.

또는 줄 아래에있는 일부 코드 month가 항상 문자열 이라고 가정하고 다음과 같은 작업을 수행 하기 때문에 원래 초기화가있을 수 있습니다.month.length 이 경우 잘못된 달 동안 예외가 발생하고 잠재적으로 호출 스크립트를 완전히 종료 할 수 있습니다.

당신이 경우 어떻게 알고 전체 컨텍스트 - 예를 들어, 그것을 모두 자신의 코드, 그리고 다른 아무도 이제까지 그것을 사용하려고하지 않습니다, 그리고 당신은 자신 당신이 미래에 변경 언젠가했다 잊지 신뢰 -이 동작을 변경하는 것이 안전 할 수있다 하지만 실제 생활에서 방어 적으로 프로그래밍하거나 동작을 철저히 문서화하는 것이 훨씬 낫다는 가정에서 많은 버그가 발생합니다.

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
}

1
아직 행동의 변화에 ​​대해 언급 한 사람이 없으므로 코드를 리팩토링 할 때이 점을 고려해야합니다.
Mauro

이 대답은 정확합니다. 다른 답변의 대부분은 미묘한 방식으로 코드의 동작을 변경합니다. 이것은 중요하지 않거나 버그를 찾기가 너무 어려워 질 수 있습니다.
Pieter B

아 그래서 항상 var를 undefined? 로 초기화하는 것이 가장 좋습니다 . 유형이 변환되면 성능이 절약됩니까?
Leon Gaban 2015

2
@LeonGaban 그것은 성능에 관한 것이 아닙니다. 원래 질문은 변수를 빈 문자열로 초기화하고 유효한 월이 선택되지 않은 경우 그대로 두었지만 여기의 다른 많은 답변은 그 사실을 무시 undefined하고 입력이 없을 때 반환하여 동작을 변경했습니다. 아니 1..12. 매우 예외적 인 상황을 제외하고는 올바른 행동이 항상 성능보다 우선합니다.
CupawnTae 2015

17

완전성을 위해 현재 답변을 보완하고 싶습니다. 기본적으로 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 '';
}

다시 한 번, 조회 테이블 또는 날짜 함수를 사용하는 것이 더 간결하고 주관적으로 더 좋습니다 .


16

배열을 사용하여 할 수 있습니다.

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

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

12

1 개의 변수 만 사용하고 범위를 벗어난 ''경우 에도 기본값을 적용하는 또 다른 옵션이 mm있습니다.

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

범위 검사 및 예외 발생도 작동 할 수 있습니다. 그리고 "오류"또는 "정의되지 않음"을 반환하는 것은 빈 문자열 대신 사용할 수 있습니다.
ChuckCottrill 2015

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.


1
나는 이것도 제안하려고했다. 간결하게 유지하면서 실제로는 매우 가독성이 좋으며 배열 솔루션에서는 그렇지 않은 희소 매핑 및 숫자가 아닌 키에 대해 잘 작동합니다. 추신 : 나는 내 대답에 대해 설명되지 않은 무작위 반대 투표를 받았습니다. 아마도 같은 드라이브 바이 아티스트 일 것입니다.
CupawnTae 2015

6

Cupawn Tae의 답변 을 바탕으로 이전에 다음과 같이 단축하겠습니다.

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

또는 예, 감사합니다.

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

건너 뛰고 (!!months[mm - 1])간단히 할 수 있습니다 months[mm - 1].
YingYang 2015

배열 인덱스가 범위를 벗어난 경우 정의되지 않습니다!
NeilElliott-NSDev 2015

months[mm - 1]undefined범위를 벗어난 인덱스를 반환 합니다. 이후 undefinedfalsy 당신은으로 끝날 것 ''의 값으로 month.
YingYang 2015-04-30

다른 답변에서 언급 var month = months[mm - 1] || '';
했듯이이

내가 더 많이 알아 차 렸지만 (내가 게시했을 때 주변이 아니었다) var month = months [mm-1] || ''; 여전히 깔끔 할 것입니다.
NeilElliott-NSDev 2015

4
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

@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까지의 숫자를 한 가지 특별한 경우뿐만 아니라 undefined잘못된 인수의 경우에는 이전에 추가 된 다른 비판과 내용을 사용하여 월 이름으로 변환합니다. 답변. ( 정확한 일치가 필요한 경우 에서 undefined로의 변경 ''은 사소 합니다.)


0

나는 wasmoo 의 해결책 을 찾고 싶지만 다음 과 같이 조정하십시오.

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

실제로는 똑같은 코드이지만 들여 쓰기가 다르기 때문에 IMO가 더 읽기 쉽습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.