[javascript] Switch statement for string matching in JavaScript

How do I write a swtich for the following conditional?

If the url contains "foo", then settings.base_url is "bar".

The following is achieving the effect required but I've a feeling this would be more manageable in a switch:

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/"
    };
}

This question is related to javascript regex switch-statement

The answer is


Just use the location.host property

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

var token = 'spo';

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


--> If the match is made the ternary expression returns the original token
----> The original token is evaluated by case

--> If the match is not made the ternary returns undefined
----> Case evaluates the token against undefined which hopefully your token is not.

The ternary test can be anything for instance in your case

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

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

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

is a ternary expression.

The test in this case is token.match(/spo/) which states the match the string held in token against the regex expression /spo/ ( which is the literal string spo in this case ).

If the expression and the string match it results in true and returns token ( which is the string the switch statement is operating on ).

Obviously token === token so the switch statement is matched and the case evaluated

It is easier to understand if you look at it in layers and understand that the turnery test is evaluated "BEFORE" the switch statement so that the switch statement only sees the results of the test.


Another option is to use input field of a regexp match result:

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;
}

It may be easier. Try to think like this:

  • first catch a string between regular characters
  • after that find "case"

:

// '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

Self-contained version that increases job security:

switch((s.match(r)||[null])[0])

_x000D_
_x000D_
function identifyCountry(hostname,only_gov=false){
    const exceptionRe = /^(?:uk|ac|eu)$/ ; //https://en.wikipedia.org/wiki/Country_code_top-level_domain#ASCII_ccTLDs_not_in_ISO_3166-1
    const h = hostname.split('.');
    const len = h.length;
    const tld = h[len-1];
    const sld = len >= 2 ? h[len-2] : null;

    if( tld.length == 2 ) {
        if( only_gov && sld != 'gov' ) return null;
        switch(  ( tld.match(exceptionRe) || [null] )[0]  ) {
         case 'uk':
            //Britain owns+uses this one
            return 'gb';
         case 'ac':
            //Ascension Island is part of the British Overseas territory
            //"Saint Helena, Ascension and Tristan da Cunha"
            return 'sh';
         case null:
            //2-letter TLD *not* in the exception list;
            //it's a valid ccTLD corresponding to its country
            return tld;
         default:
            //2-letter TLD *in* the exception list (e.g.: .eu);
            //it's not a valid ccTLD and we don't know the country
            return null;
        }
    } else if( tld == 'gov' ) {
        //AMERICAAA
        return 'us';
    } else {
        return null;
    }
}
_x000D_
<p>Click the following domains:</p>
<ul onclick="console.log(`${identifyCountry(event.target.textContent)} <= ${event.target.textContent}`);">
    <li>example.com</li>
    <li>example.co.uk</li>
    <li>example.eu</li>
    <li>example.ca</li>
    <li>example.ac</li>
    <li>example.gov</li>
</ul>
_x000D_
_x000D_
_x000D_

Honestly, though, you could just do something like

function switchableMatch(s,r){
    //returns the FIRST match of r on s; otherwise, null
    const m = s.match(r);
    if(m) return m[0];
    else return null;
}

and then later switch(switchableMatch(s,r)){…}


Might be too late and all, but I liked this in case assignment :)

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;
        }
    });
};

you could event take it further, and pass a list of option and handle the regex with |


RegExp can be used on the input string not just technically but practically with the match method too.

Because the output of the match() is an array we need to retrieve the first array element of the result. When the match fails, the function returns null. To avoid an exception error we will add the || conditional operator before accessing the first array element and test against the input property that is a static property of regular expressions that contains the input string.

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;
}

Another approach is to use the String() constructor to convert the resulting array that must have only 1 element (no capturing groups) and whole string must be captured with quanitifiers (.*) to a string. In case of a failure the null object will become a "null" string. Not convenient.

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

Anyway, a more elegant solution is to use the /^find-this-in/.test(str) with switch (true) method which simply returns a boolean value and it's easier to search without case sensitivity.


You could also make use of the default case like this:

    switch (name) {
        case 't':
            return filter.getType();
        case 'c':
            return (filter.getCategory());
        default:
            if (name.startsWith('f-')) {
                return filter.getFeatures({type: name})
            }
    }

Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to regex

Why my regexp for hyphenated words doesn't work? grep's at sign caught as whitespace Preg_match backtrack error regex match any single character (one character only) re.sub erroring with "Expected string or bytes-like object" Only numbers. Input number in React Visual Studio Code Search and Replace with Regular Expressions Strip / trim all strings of a dataframe return string with first match Regex How to capture multiple repeated groups?

Examples related to switch-statement

Switch in Laravel 5 - Blade Switch case: can I use a range instead of a one number SQL use CASE statement in WHERE IN clause SSRS Conditional Formatting Switch or IIF Switch statement equivalent in Windows batch file OR operator in switch-case? Regarding Java switch statements - using return and omitting breaks in each case Using two values for one switch case statement C# how to use enum with switch Switch statement multiple cases in JavaScript