JavaScriptでの文字列照合のSwitchステートメント


193

次の条件付きのswtichを作成するにはどうすればよいですか?

URL が含まれている場合「foo」 settings.base_urlは「bar」です。

以下は必要な効果を達成していますが、これはスイッチでより管理しやすいと感じています。

var doc_location = document.location.href;
var url_strip = new RegExp("http:\/\/.*\/");
var base_url = url_strip.exec(doc_location)
var base_url_string = base_url[0];

//BASE URL CASES

// LOCAL
if (base_url_string.indexOf('xxx.local') > -1) {
    settings = {
        "base_url" : "http://xxx.local/"
    };
}

// DEV
if (base_url_string.indexOf('xxx.dev.yyy.com') > -1) {
    settings = {
        "base_url" : "http://xxx.dev.yyy.com/xxx/"
    };
}

回答:


352

完全な文字列マッチングを行わswitchない限り、でそれを行うことはできません。それは部分文字列マッチングを行っています。 ショーンがコメントで指摘しているように、これは完全に真実ではありません。最後の注を参照してください。)

上部の正規表現が一致で比較したくないすべてのものを取り除いて満足している場合は、部分文字列の一致は必要ありません。

switch (base_url_string) {
    case "xxx.local":
        // Blah
        break;
    case "xxx.dev.yyy.com":
        // Blah
        break;
}

...しかし、繰り返しますが、これは、一致する完全な文字列である場合にのみ機能します。base_url_stringたとえば「yyy.xxx.local」の場合は失敗しますが、現在のコードは「xxx.local」ブランチのコードと一致します。


更新:さて、技術的にswitch部分文字列の照合にを使用できます、ほとんどの状況ではお勧めしません。方法は次のとおりです(実例):

function test(str) {
    switch (true) {
      case /xyz/.test(str):
        display("• Matched 'xyz' test");
        break;
      case /test/.test(str):
        display("• Matched 'test' test");
        break;
      case /ing/.test(str):
        display("• Matched 'ing' test");
        break;
      default:
        display("• Didn't match any test");
        break;
    }
}

これは、JavaScript switchステートメントの動作方法、特に2つの重要な側面のために機能します。1つ目は、ケースがソーステキストの順序で考慮されること、2つ目は、セレクター式(キーワードの後のビットcase)が、そのケースとして評価されるであることです。評価されます(他の一部の言語のように定数ではありません)。したがって、テスト式はtrueであるためcase、結果の最初の式trueが使用されます。


91
私はそれが古いです知っているが、これはかなり真実ではない-あなたが実際に行うことができますswitch(true) { case /foo/.test(bar): ....
ショーン・キンゼイ

23
なんてこった!Switchステートメントは、そのように機能するはずではありません。これは単に壊れているので、そのようなことをすることは違法であるべきです。
Pijusn 2013

47
Hoohoo、とてもおいしく悪です。
Aditya MP

41
あなただけがあなたの視点を広げる必要があります。これはRubyの標準ですが、醜いのではなく、trueそのままにしておくだけです。
emkman 14

49
私はこれが大好きで、それを認めることを恥ずかしくはありません。
chrisf 2014

65

RegExpは、技術的にだけでなく、matchメソッドでも実際に入力文字列で使用できます。

の出力はmatch()配列なので、結果の最初の配列要素を取得する必要があります。一致が失敗すると、関数はを返しますnull。例外エラーを回避する||ために、最初の配列要素にアクセスする前に条件演算子を追加し、入力文字列を含む正規表現の静的プロパティであるinputプロパティに対してテストします。

str = 'XYZ test';
switch (str) {
  case (str.match(/^xyz/) || {}).input:
    console.log("Matched a string that starts with 'xyz'");
    break;
  case (str.match(/test/) || {}).input:
    console.log("Matched the 'test' substring");        
    break;
  default:
    console.log("Didn't match");
    break;
}

別のアプローチは、String()コンストラクターを使用して、要素が1つのみ(キャプチャグループなし)である必要がある結果の配列を変換し、文字列全体を限定子(.*)で文字列にキャプチャする必要があることです。失敗した場合、nullオブジェクトは"null"文字列になります。便利でない。

str = 'haystack';
switch (str) {
  case String(str.match(/^hay.*/)):
    console.log("Matched a string that starts with 'hay'");
    break;
}

とにかく、よりエレガントな解決策は、ブール値を返すだけの/^find-this-in/.test(str)with switch (true)メソッドを使用することです。大文字と小文字を区別せずに検索する方が簡単です。


1
pribilinsiky:(test()を使用する)3番目のソリューションではswitch(true)が必要であることをおそらく言及する必要があります。
2015年

35

location.hostプロパティを使用するだけです

switch (location.host) {
    case "xxx.local":
        settings = ...
        break;
    case "xxx.dev.yyy.com":
        settings = ...
        break;
}

1
ありがとう、+ 1これは私が実際にやるべきことです
フランケンシュタイン博士、

switchステートメントに渡す変数の型に注意する必要があります。それはしなければならない文字列です。あなたができることを確認するためにswitch ("" + location.host)
2013

16

別のオプションはinput正規表現の一致結果のフィールドを使用することです:

str = 'XYZ test';
switch (str) {
  case (str.match(/^xyz/) || {}).input:
    console.log("Matched a string that starts with 'xyz'");
    break;
  case (str.match(/test/) || {}).input:
    console.log("Matched the 'test' substring");        
    break;
  default:
    console.log("Didn't match");
    break;
}

良いですね。この場合、任意の配列プロパティもテストに使用できます。たとえば.length:
Steven Pribilinskiy

6
var token = 'spo';

switch(token){
    case ( (token.match(/spo/) )? token : undefined ) :
       console.log('MATCHED')    
    break;;
    default:
       console.log('NO MATCH')
    break;;
}


->一致した場合、3項式は元のトークンを返します
---->元のトークンは大文字と小文字で評価されます

->一致しなかった場合、3項は未定義を返します
----> Caseはトークンをundefinedに対して評価しますが、トークンがそうでないことを期待します。

3値テストは、たとえば、あなたのケースでは何でもかまいません

( !!~ base_url_string.indexOf('xxx.dev.yyy.com') )? xxx.dev.yyy.com : undefined 

===========================================

(token.match(/spo/) )? token : undefined ) 

ある三元表現。

この場合のテストは、token.match(/ spo /)です。これは、正規表現の/ spo /(この場合はリテラル文字列spo)に対してトークンに保持されている文字列との一致を示します。

式と文字列が一致した場合、結果はtrueになり、トークン(スイッチステートメントが操作している文字列)を返します。

明らかにトークン===トークンなので、switchステートメントが一致し、ケースが評価されます

レイヤーで見ると、ターナリーテストがスイッチステートメントの「前に」評価され、スイッチステートメントがテストの結果のみを表示することを理解すると、理解しやすくなります。


あなたの答えは混乱しています。例と説明を見直して改善できますか?
ファルサレッラ2014

@falsarella理解できないと思った部分を説明しました。私はもっ​​と簡単な例を作ることはできないと思います。他に質問がある場合や、問題を具体的に説明できる場合は、もっとお手伝いできます。
ジェームズ

はい、わかりました。それtoken.match(/spo/)が一致するのは明らかなので、私は混乱しました。
ファルサレッラ2014

3

簡単かもしれません。次のように考えてみてください。

  • 最初に通常の文字の間の文字列をキャッチします
  • その後、「ケース」を見つけます

// 'www.dev.yyy.com'
// 'xxx.foo.pl'

var url = "xxx.foo.pl";

switch (url.match(/\..*.\./)[0]){
   case ".dev.yyy." :
          console.log("xxx.dev.yyy.com");break;

   case ".some.":
          console.log("xxx.foo.pl");break;
} //end switch

賛成。ただし、注:TypeError: url.match(...) is null
1111161171159459134

1

遅すぎるかもしれませんが、ケースの割り当てではこれが好きでした:)

function extractParameters(args) {
    function getCase(arg, key) {
        return arg.match(new RegExp(`${key}=(.*)`)) || {};
    }

    args.forEach((arg) => {
        console.log("arg: " + arg);
        let match;
        switch (arg) {
            case (match = getCase(arg, "--user")).input:
            case (match = getCase(arg, "-u")).input:
                userName = match[1];
                break;

            case (match = getCase(arg, "--password")).input:
            case (match = getCase(arg, "-p")).input:
                password = match[1];
                break;

            case (match = getCase(arg, "--branch")).input:
            case (match = getCase(arg, "-b")).input:
                branch = match[1];
                break;
        }
    });
};

あなたはそれをさらにイベントに取り、オプションのリストを渡し、|で正規表現を処理することができます


1
また、タイプセーフのためにに変更|| {}することもできます|| [-1]。また、new RegExpスラッシュだけでなく、なぜ使用されているのですか?
セルゲイKrasilnikov

本当にそれを洗練するのに時間はかかりませんでした..それがうまくいった瞬間、私は続けました.....今は恥ずかしいです
TacB0sS

パニックに陥らないでください、それは私の単なるつまらないものでした;)実際、私が正しいかどうかさえ確信がありません。
セルゲイKrasilnikov

いいえ...あなたは正しいです...私は間違いなくジェネリファイとプリティファイをすることができます..そのコードに再び到達したときに私はそうします..すぐに十分でしょう:)
TacB0sS
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.