web-dev-qa-db-fra.com

Comment raccourcir le bloc de cas de commutation convertissant un nombre en nom de mois?

Existe-t-il un moyen d'écrire cela sur moins de lignes, mais toujours facilement lisible?

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

Définissez un tableau, puis récupérez par index.

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

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

qu'en est-il de ne pas utiliser de tableau du tout :)

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

selon cette réponse Obtenez le nom du mois à partir de la date de David Storey

81
vidriduch

Essaye ça:

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

Notez que mm peut être un entier ou une chaîne et cela fonctionnera toujours.

Si vous souhaitez que les clés non existantes entraînent une chaîne vide '' (au lieu de undefined), puis ajoutez cette ligne:

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

JSFiddle .

Vous pouvez créer un tableau à la place et rechercher le nom du mois:

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


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

Voir la réponse de @CupawnTae pour le rationnel derrière le code || ''

26
Jaco

Faites attention!

La chose qui devrait immédiatement déclencher des alarmes est la première ligne: var month = ''; - pourquoi cette variable est-elle initialisée sur une chaîne vide, plutôt que null ou undefined? Il peut simplement s'agir d'une habitude ou d'un code copié/collé, mais à moins que vous ne le sachiez à coup sûr, il n'est pas sûr de l'ignorer lorsque vous refactorisez du code.

Si vous utilisez un tableau de noms de mois et modifiez votre code en var month = months[mm-1];, Vous modifiez le comportement, car maintenant pour les nombres en dehors de la plage ou les valeurs non numériques, month sera undefined. Vous savez peut-être que c'est correct, mais il y a de nombreuses situations où ce serait mauvais.

Par exemple, disons que votre switch est dans une fonction monthToName(mm), et quelqu'un appelle votre fonction comme ceci:

var monthName = monthToName(mm);

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

Maintenant, si vous changez en utilisant un tableau et en retournant monthName[mm-1], Le code appelant ne fonctionnera plus comme prévu, et il soumettra des valeurs undefined lorsqu'il est censé afficher un avertissement. Je ne dis pas que c'est un bon code , mais à moins de savoir exactement comment le code est utilisé, vous ne pouvez pas faire d'hypothèses.

Ou peut-être que l'initialisation d'origine était là parce qu'un code plus bas suppose que month sera toujours une chaîne et fera quelque chose comme month.length - cela entraînera la levée d'une exception pour les mois invalides et potentiellement tuer complètement le script appelant.

Si vous connaissez l'ensemble du contexte - par exemple c'est tout votre propre code, et personne d'autre ne pourra jamais l'utiliser, et vous vous fiez en vous-même, n'oubliez pas que vous avez fait le changement dans le futur - il peut être sûr de changer le comportement comme celui-ci, mais trop de bogues proviennent de ce genre d'hypothèse selon laquelle dans la vie réelle, il vaut mieux programmer de manière défensive et/ou documenter le comportement à fond.

réponse de Wasmoo fait les choses correctement (EDIT: un certain nombre d'autres réponses, y compris celle acceptée, ont maintenant été corrigées également) - vous pouvez utiliser months[mm-1] || '' ou si vous préférez rendre plus clair en un coup d'œil ce qui se passe, quelque chose comme:

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

Pour être complet, je voudrais compléter les réponses actuelles. Fondamentalement, vous pouvez annuler le mot clé break et retourner directement une valeur appropriée. Cette tactique est utile si la valeur ne peut pas être stockée dans une table de recherche précalculée.

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

Encore une fois, l'utilisation d'une table de recherche ou de fonctions de date est plus succincte et subjective mieux.

17
Gerard

Vous pouvez le faire en utilisant un tableau:

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

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

Voici une autre option qui n'utilise qu'une seule variable et applique toujours la valeur par défaut '' lorsque mm est en dehors de la plage.

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

Vous pouvez l'écrire en tant qu'expression au lieu d'un commutateur, en utilisant des opérateurs conditionnels:

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' :
  '';

Si vous n'avez jamais vu d'opérateurs conditionnels chaînés auparavant, cela peut sembler plus difficile à lire au premier abord. L'écrire en tant qu'expression rend un aspect encore plus facile à voir que le code d'origine; il est clair que l'intention du code est d'assigner une valeur à la variable month.

9
Guffa

S'appuyant sur Cupawn Tae's réponse précédente, je le raccourcirais à:

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

Alternativement, oui, j'apprécie, moins lisible:

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

Comme @vidriduch, je voudrais souligner l'importance du code i20y ("internationalisability") dans le contexte actuel et suggérer la solution concise et robuste suivante avec le test unitaire.

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

J'essaie de rester aussi proche que possible de la question d'origine, c'est-à-dire de transformer les numéros 1 à 12 en noms de mois, non seulement pour un cas spécial, mais de retourner undefined en cas d'arguments invalides, en utilisant certains des anciens ajoutés critique et contenu des autres réponses. (Le passage de undefined à '' est trivial, au cas où exact une correspondance est nécessaire.)

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

Je choisirais la solution de wasmoo , mais ajustez-la comme ceci:

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

C'est exactement le même code, vraiment, mais différemment indenté, que l'OMI le rend plus lisible.

0
John Slegers