【问题标题】:Better solution than a switch statement比 switch 语句更好的解决方案
【发布时间】:2013-02-18 09:29:46
【问题描述】:

下面是一个从循环中的数组中提取月份的函数。当找到一个月时,该月将在对象 CRIMES_PER_MONTH 中迭代 1。

这可行,但它是一个非常丑陋的解决方案,并且 switch 语句会变得很长。那么,我可以用什么来代替 switch 语句呢?

var crimes_per_month = {
          january: 0,
          february: 0,
          mars: 0,
          april: 0,
          may: 0,
          june: 0,
          july: 0,
          august: 0,
          september: 0,
          oktober: 0,
          november: 0,
          december: 0
};

function AddToMonths(month) {

    switch(month) {

        case 1:
            jan += 1;
        break;

        case 2:
            feb += 1;
        break;

        case 3:
            mar += 1;
        break;

        case 4:
            apr += 1;
        break;

        ... and so on...

    }
}

for(var i = 0; i < incidents.length; i++) {
    month = incidents[i].substring(5, 7);
    AddToMonths(parseInt(month));
}

我想最好的办法是直接在循环中访问对象:

for(var i = 0; i < incidents.length; i++) {
    month = incidents[i].substring(5, 7);
    crimes_per_month[month] += 1;
}

...但这仅适用于数组,我真的想将其保留为对象。

【问题讨论】:

    标签: javascript loops refactoring switch-statement


    【解决方案1】:

    crimes_per_month 制作成一个数组是最简单的,这样它的属性就可以直接用addToMonths 给出的键来寻址:

    crimes_per_month = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
    function addToMonths(month) {
        crimes_per_month[month-1] += 1;
    }
    

    如果你不想这样,你需要做一个索引到月份名称的转换函数。

    var crimes_per_month = {
        january: 0,
        february: 0,
        mars: 0,
        april: 0,
        may: 0,
        june: 0,
        july: 0,
        august: 0,
        september: 0,
        oktober: 0,
        november: 0,
        december: 0
    };
    
    function addToMonths(month) {
        var names = ["january", "february", "mars", "april", "may", "june", "july", "august", "september", "oktober", "november", "december"];
        var name = names[month-1];
        crimes_per_month[name] += 1;
    }
    

    【讨论】:

    • 完成后有没有办法将数组转换为对象?我真的需要把它作为一个对象。
    • 当然可以。只需将值映射到对象上,然后使用索引到名称的转换来获取属性名称。
    【解决方案2】:

    你可以简单地使用一个数组。

    var crime_per_month = new Array(13);
    for(var i = 1; i <= 12; i++) crime_per_month[i] = 0;
    function AddToMonths(month) {
        crime_per_month[month]++;
    }
    

    【讨论】:

    • 年份什么时候有13个月?
    • 他想要从 1 到 12 的月份,但是数组中的第一个元素是 0,所以他需要 13 个元素...呵呵!
    • 我很确定目标通常是将集合转置回基于 0 的数组,而不是尝试填充索引为 0 的集合以匹配问题的范围......
    【解决方案3】:

    如果您想保持当前的CRIMES_PER_MONTH 结构,可以使用带键的数组将月份编号转换为键名:

    var addToMonths = (function () {
        var names = ["january", "february", "mars", "april", "may", "june", "july", "august", "september", "oktober", "november", "december"];
        return function (month) {
            CRIMES_PER_MONTH[names[month - 1]]++;
        };
    }());
    

    【讨论】:

    • 对象没有顺序,所以你不能确定得到正确的索引。不过,很好的关闭。
    【解决方案4】:

    只要有一个月份名称数组,您可以查找。

    var months = ["january", "february", ...],
        month = incidents[i].substring(...),
    
        incident_month = months[month-1]; // case 1: === "january"
    
     crimes_per_month[incident_month] += 1; // case 1: === crimes_per_month.january += 1
    

    【讨论】:

      【解决方案5】:

      我在这里明显遗漏了什么吗?

      它是 JavaScript,所以(几乎)一切都是允许的;)

      为什么不直接访问对象成员? 您需要在 crimes_per_monthincidents_month 中使用相同的成员名称,并且应该能够执行以下操作:

      var crimes_per_month = {january: 0,...};
      var incidents_month = {january: 14,....};
      
      function addToMonth(/* string */ monthName) {
        crimes_per_month[monthName] = crimes_per_month[monthName] + 1;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-03-30
        • 2017-06-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多