2012-06-26 18 views
5

Rails 3.2 jqueryモバイルアプリケーションでハンドルバーを使用しています。Coffeescriptのswitch case文の範囲

私はどんな結果を得ていないのです

Handlebars.registerHelper 'status', (blog) -> 
    switch(parseInt(blog.status)) 
    when [0..20] 
     status = "active" 
    when [20..40] 
     status = "Moderately Active" 
    when [40..60] 
     status = "Very Active" 
    when [60..100] 
     status = "Hyper Active" 
    return status 

などのCoffeeScriptのメソッドの内部スイッチのcase文を記述しようとしています。どのように範囲をいつ使用するか。お申し込みください

+2

これはなぜ機能しますか?この[github issue](https://github.com/jashkenas/coffee-script/issues/1383)は、この構文が受け入れられなかったと言われています。 –

答えて

16

お客様のswitchは、コメントにCygalの注釈(つまりissue 1383を参照)としては機能しません。 switchはちょうど見せかけif(a == b)構造であり、あなたは、のようなものを言うことができるようにする必要があります:

a = [1,2,3] 
switch a 
... 

をし、それが動作しているときに、アレイ上switch。 CoffeeScriptのデザイナーは、配列(すべて[a..b])を処理するために(壊れやすい)特別なケースを追加することは特別に価値がないと考えていました。

あなたはifでそれを行うことができます:あなたはあなたのために文字列を追加する必要がある3つの特別なケースを持って

Handlebars.registerHelper 'status', (blog) -> 
    status = parseInt(blog.status, 10) 
    return 'Something...'  if status <= 0 
    return 'Active'   if status <= 20 
    return 'Moderately Active' if status <= 40 
    return 'Very Active'  if status <= 60 
    return 'Hyper Active'  if status <= 100 
    return 'Something else' # This return isn't necessary but I like the symmetry 

注:

Handlebars.registerHelper 'status', (blog) -> 
    status = parseInt(blog.status, 10) 
    if 0 <= status <= 20 
    'Active' 
    else if 20 < status <= 40 
    'Moderately Active' 
    else if 40 < status <= 60 
    'Very Active' 
    else if 60 < status <= 100 
    'Hyper Active' 
    else 
    # You need to figure out what to say here 

それともreturnのこのような短絡で:

  1. status < 0
  2. status > 100
  3. statusは、NaNである。このケースは通常NaN => nNaN <= nの両方がすべてnに対してfalseであるため、最終的に "それは100以下ではない"分岐の下にあります。

はい、ステータスが常に想定される範囲内にあることは間違いありません。一方、不可能なのはいつもソフトウェア(comp.risksメーリングリスト)であり、穴を空けておくと正当な理由がありません。

parseIntコールに基数引数を追加すると、先行ゼロが物事を混乱させたくないことにも注意してください。はい、基数引数はオプションですが、実際にはそうすべきではありません。そしてparseIntの呼び出しごとに指が自動的に, 10を追加するはずです。 mu is too short's answerに小さなビットを追加

+1

そのような良い答え:D。私は第二の解決策の簡潔さが気に入っていますが、第一の解決策の「表現可能性」もそうです。 'swtich '式(http://goo.gl/QKKAq)を使って両方を参加させることを提案できますか? = D(私は新しい回答としてそれを掲示しているポイントを盗もうとは思わない) – epidemian

+0

@epidemian:それは私の良い選択のように見える、私は多くの点を持っているので、あなたはそれを答え。私はおそらく2番目を使用して、私は "インラインルックアップテーブル"効果が好きです。 –

+0

OK、あなたの付録として回答を追加しました。 – epidemian

8

、あなたがswitch式にその2番目のコードスニペットを変換することができます。

Handlebars.registerHelper 'status', (blog) -> 
    status = parseInt(blog.status, 10) 
    switch 
    when status <= 0 then 'Something...'  
    when status <= 20 then 'Active' 
    when status <= 40 then 'Moderately Active' 
    when status <= 60 then 'Very Active' 
    when status <= 100 then 'Hyper Active' 
    else 'Something else' 

CSコンパイラはswitch (false) statement with the negated conditionsに生成されますが、これは(基本的にJavaScriptでswitch (true)を行うことと等価ですブール値の結果を式から確実に...私は考える)。


と範囲を超えるswitchが動作しない理由は、(for i in [1..something]ような何かをやったときに、コンパイラは、いくつかの最適化のトリックを行うだろうが)CSでのリテラルは、昔ながらのJSの配列を表現範囲であることがあるので、彼らがしていますそれらが処理されるswitch中に発見だけlike normal array values

// Generated JS for question's CS code: 
switch (parseInt(blog.status)) { 
    case [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]: 
    status = "active"; 
    break; 
    case [20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40]: 
    status = "Moderately Active"; 
    break; 
    case [40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60]: 
    status = "Very Active"; 
    break; 
    case (function() { 
     _results = []; 
     for (_i = 60; _i <= 100; _i++){ _results.push(_i); } 
     return _results; 
    }).apply(this): 
    status = "Hyper Active"; 
} 

switchステートメント内の値は、基本的にのみ配列のためではない、プリミティブのために働く===を使用して、各case値と比較されます(そして、たとえそれが配列のために働いていても、のed値がcase ed配列に含まれている場合ではなく、配列の等価性をテストすることになります)。

+1

参照してください、それは価値があった。私はそのような形の「スイッチ」を考えなかったが、次回はそうするだろう。私はあなたが正しいと思っていますが、ブール値のコンテキストと 'switch(true)'の代わりに 'switch(false)'を使っています。 –

関連する問題