2

現在、比較のために次のコードを使用していますが、ご覧のとおり、大量の 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'
4

7 に答える 7

5

あなたは地図を使うことができます

var rules = {
    'female': {
        'he': 'she',
        'his': 'her',
        // ...
    },
    'male': {
        'he': 'he',
        // ...
    },
    'default': {
        'he': 'he/she'
        // ...
    }
};

this.gender_ref = rules[gender ? gender : 'default'][grammer];

これは拡張可能であり、別のバックエンド(DBなど)から動的に生成することもできます。

編集(Linus G Thielによる) coffeescriptでも同じ:

rules =
  female:
    he: 'she'
    his: 'her'
    // ...
  male:
    he: 'he'
    // ...
  default:
    he: 'he/she'
    // ...

@gender_ref = rules[gender or 'default'][grammer]
于 2012-11-23T08:47:43.623 に答える
2

多次元ハッシュ テーブルを使用します。

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]
于 2012-11-23T08:51:55.207 に答える
2

map を使用して、可能な値をキャッシュします。いつでも拡張でき、メソッドを簡素化できます。

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];
  }
}
于 2012-11-23T08:54:24.590 に答える
2

switch ステートメントの使用を検討する

switch (gender) {
  case "1":
    alert("");
    break;
  case "2":
    alert("");
    break;
  case "3":
    alert("");
    break;
  case "4":
    alert("");
    break;
  default:
    alert("default");
    break;
}
于 2012-11-23T08:43:12.270 に答える
1

次のように、長さを少し再利用できます。

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'

さまざまな出力オプションがあるため、これよりも大幅に短くすることはできません。switch / 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];
于 2012-11-23T08:51:25.257 に答える
1

ステップバイステップで進めば簡単です。そのように複雑な条件をリファクタリングする方法を学びます。

ifまず、最初のとその後else ifの に共通のチェックがあることに注意してください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 のスイッチは状況に合わせてうまく機能し、コードをかなり読みやすく、複雑さを軽減します。これをさらに最適化できます。


これは簡単な最適化で、ステートメント@gender_refの先頭でへの代入を行います (ここでも、共通部分を取り除きます)。switch

  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'

代入を親ifに移動することで、さらに最適化できます@gender_ref =(ただし、else句では機能しません...なぜだろうか)。

于 2012-11-23T10:01:51.543 に答える
0

パフォーマンスに関しては、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';
}
于 2012-11-23T09:15:55.170 に答える