【问题标题】:How can I simplify the code for multiple nested if else statements如何简化多个嵌套 if else 语句的代码
【发布时间】:2012-11-23 22:08:37
【问题描述】:

我目前正在使用以下代码进行比较,但正如您所见,我正在制作大量的 if else 语句。有没有办法简化代码并提高效率?

getGenderRef: (grammer=nil) ->
  @gender_ref = ""
  gender = this.get('gender')
  if gender? and gender == 'male'
    if grammer == 'he'
      @gender_ref = 'he'
    else if grammer == 'his'
      @gender_ref == 'his'
    else if grammer == 'him'
      @gender_ref == 'him'
  else if gender? and gender == 'female'
    if grammer == 'he'
      @gender_ref = 'she'
    else if grammer == 'his'
      @gender_ref == 'her'
    else if grammer == 'him'
      @gender_ref == 'her'
  else if gender? or gender == null
    if grammer == 'he'
      @gender_ref = 'he/she'
    else if grammer == 'his'
      @gender_ref == 'his/her'
    else if grammer == 'him'
      @gender_ref == 'him/her'

【问题讨论】:

    标签: javascript if-statement coffeescript


    【解决方案1】:

    你可以使用地图

    var rules = {
        'female': {
            'he': 'she',
            'his': 'her',
            // ...
        },
        'male': {
            'he': 'he',
            // ...
        },
        'default': {
            'he': 'he/she'
            // ...
        }
    };
    
    this.gender_ref = rules[gender ? gender : 'default'][grammer];
    

    它是可扩展的,也可以从另一个后端(例如数据库)动态生成。

    编辑(由 Linus G Thiel) 在 coffeescript 中相同:

    rules =
      female:
        he: 'she'
        his: 'her'
        // ...
      male:
        he: 'he'
        // ...
      default:
        he: 'he/she'
        // ...
    
    @gender_ref = rules[gender or 'default'][grammer]
    

    【讨论】:

      【解决方案2】:

      使用地图缓存可能的值。您可以在任何时候扩展它,并且能够简化您的方法:

      var genders = {
          "male" : {
             "he": "he",
             "his": "his",
             "him": "him"
         },
         "female" : {
             "he": "she",
             "his": "her",
             "him": "her" 
         },
         "null": {
            "he": "he/she",
            "his": "his/her",
            "him": "him/her"
         }
      }
      
      function getGenderRef (grammer) {
        var gender_ref = "",
            availableGenders = genders[this.get('gender')];
      
        if (availableGenders) {
            gender_ref = availableGenders[grammer];
        }
      }
      

      【讨论】:

        【解决方案3】:

        考虑使用 switch 语句

        switch (gender) {
          case "1":
            alert("");
            break;
          case "2":
            alert("");
            break;
          case "3":
            alert("");
            break;
          case "4":
            alert("");
            break;
          default:
            alert("default");
            break;
        }
        

        【讨论】:

          【解决方案4】:

          使用多维哈希表。

          grammarByGender = {
              "male": { "he" : "he", "his": "his", "him": "him" },
              "female": {"he" : "she", "his" :"her", "him":"her"},
              "neuter": {"he":"he/she","his":"his/her","him":"him/her"}
          }
          
          @gender_ref = grammarByGender[this.get("gender")][grammer]
          

          【讨论】:

          • 不错的答案。我喜欢使用"neuter" :)。不过,它混合了 CoffeeScript 和 JS 语法。我建议使用 Coffee 的无括号对象文字以使代码不那么拥挤,并在 grammarByGender[...] 访问权限上添加一个条件,以便在没有性别时使用 "neuter"Example.
          • here's another example 使用一个小函数来避免一些代码重复:)
          【解决方案5】:

          您可以按如下方式稍微减少长度:

          getGenderRef: (grammer=nil) ->
            @gender_ref = ""
            gender = this.get('gender')
            if gender? and gender == 'male'
              if grammer == 'he'
                @gender_ref = 'he'
              else if grammer == 'his'
                @gender_ref == 'his'
              else if grammer == 'him'
                @gender_ref == 'him'
            else if gender? and gender == 'female'
              if grammer == 'he'
                @gender_ref = 'she'
              else if grammer == 'his' or grammer == 'him'
                @gender_ref == 'her'
            else if gender? or gender == null
              if grammer == 'he'
                @gender_ref = 'he/she'
              else if grammer == 'his'
                @gender_ref == 'his/her'
              else if grammer == 'him'
                @gender_ref == 'him/her'
          

          你不能让它比这更短,因为你有很多不同的输出选项。 一个 swtich / case 可能是一个选项,但这将是一样多的代码。

          另一种选择是使用对象:

          references = {
              'male': {
                  'he': 'he',
                  'his': 'his',
                  'him': 'him'
              },
              'female': {
                  'he': 'she',
                  'his': 'her',
                  'him': 'her'
              },
              'null':{
                  'he': 'he/she',
                  'his': 'his/her',
                  'him': 'him/her'
              }
          }
          //Access:
          gender_ref = references[gender ? gender : 'null'][gender_ref];
          

          【讨论】:

          • 这不是菲利克斯刚刚建议的吗?顺便说一句,默认值不再有效,因为您将键名更改为 null。
          • 我猜,但我是在发帖后才看到的。我们不能使用'null' 字符串作为键吗?
          • 您的地图看起来与 Felix 的版本惊人地相同,相同的引号、相同的顺序、相同的变量名...
          • @Christoph 也许那是因为我使用了问题中指定的变量和顺序。在 2 个答案具有相同代码之前,我已经发生过这种情况,仅仅是因为应该这样做。另外,我总是使用单引号:php habit.
          【解决方案6】:

          如果你一步一步来,那会很容易。您将学习如何以这种方式重构复杂的条件。

          首先,请注意您在第一个if 及其后续else ifs 中有一个共同检查,即if gender?。你应该把它作为一个常见的检查和重构你的代码如下:

            if gender?
              ...
            else # if gender == null
              ...
          

          这构成了您的主要 if 和 else 子句。您将在这些下嵌套 if 和 switch 语句。重构后的 if/else 代码如下:

            if gender?
              if gender == 'male'
                switch grammer
                  when 'he' then @gender_ref = 'he'
                  when 'his' then @gender_ref = 'his'
                  when 'him' then @gender_ref = 'him'
              else if gender == 'female'
                switch grammer
                  when 'he' then @gender_ref = 'she'
                  when 'his' then @gender_ref = 'her'
                  when 'him' then @gender_ref = 'her'
            else # if gender == null
              switch grammer
                when 'he' then @gender_ref = 'he/she'
                when 'his' then @gender_ref = 'his/her'
                when 'him' then @gender_ref = 'him/her'
          

          Coffeescript 中的开关可以很好地适应您的情况,使代码非常易读且不那么复杂。您可以进一步优化。


          这是一个简单的优化,您在switch 语句的开头对@gender_ref 进行赋值(同样,去掉公共部分):

            if gender?
              if gender == 'male'
                @gender_ref = switch grammer
                  when 'he' then 'he'
                  when 'his' then 'his'
                  when 'him' then 'him'
              else if gender == 'female'
                @gender_ref = switch grammer
                  when 'he' then 'she'
                  when 'his' then 'her'
                  when 'him' then 'her'
            else # if gender == null
              @gender_ref = switch grammer
                when 'he' then 'he/she'
                when 'his' then 'his/her'
                when 'him' then 'him/her'
          

          您可以通过将 @gender_ref = 赋值移动到父 if 来进一步优化它(虽然它在 else 子句中不起作用......我想知道为什么)。

          【讨论】:

            【解决方案7】:

            就性能而言,if 语句没有任何问题。我不禁想知道这是否不仅仅是关于可读性。

            无论如何,这里还有另一个选项仍在使用 if 语句。

            @gender_ref = grammer; // male values are the same so use as default
            
            if(  gender == "female" ) {
            
                if( grammer == 'he' ) @gender_ref = 'she';
                if( grammer == 'his' ) @gender_ref = 'her';
                if( grammer == 'him' ) @gender_ref = 'her';
            
            } else if (  !gender ) { // if not defined
            
                if( grammer == 'he' ) @gender_ref = 'he/she';
                if( grammer == 'his' ) @gender_ref = 'his/her';
                if( grammer == 'him' ) @gender_ref = 'him/her';
            }
            

            【讨论】:

            • 通过将else if 替换为if,您正在改变代码的行为...
            • 也缺少嵌套的if...;)
            • 虽然行为不同,但输出是一样的。
            • 这是对的,但这仍然很危险,因为您无法确保输出事实不会由于不同的行为而有所不同。因此,不应该在不告诉 OP 的情况下更改代码。也许他以后不会注意到并遇到麻烦——谁知道呢?
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2021-09-05
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多