views:

150

answers:

5

I have the following if, else if, else construct and I am just curious how I could convert such as construct into a switch statement.

var emailSubject = email.subject.toLowerCase(); 
if(emailSubject.indexOf("account request") >= 0){
     //do acct req
}else if(emailSubject.indexOf("accounts pending removal for") >= 0){
     //do account removal 
}else if(emailSubject.indexOf("listserv application") >= 0){
     //do listserv app 
}else if(emailSubject.indexOf("student organization webmaster transfer request") >= 0){
     //do webmaster xfer 
}else{
     //do default 

} 

My thoughts are but I do not think this is correct:

switch(emailSubject){
    case this.indexOf("account request"):
       //do acct request 
       break;
    default:
       //do default 
}

Or

switch(0){
   case emailSubject.indexOf("accounts pending removal"):
     //process account pending removal 
     break;
   default:
     //do default behavior 
}
+4  A: 

Your example code cannot easily be converted to a switch statement in most languages, nor should it. switch is for comparing a single variable against a range of constant values, whereas your logic requires comparison against non-constant values, with no variable to compare them with. if/else if is the correct construction for your case.

JSBangs
I understand the practicality aspect of it, but it was more of a thought provoking question I had while writing some code. Cheers.
Chris
@Chris, your proposed `switch` statement is a syntax error in most languages, including, AFAIK, javascript. That's because the values for the `case` statements must be constant values, not the result of runtime calculations.
JSBangs
+2  A: 

You can only use case to check a value:

switch(emailSubject){
    case "Subject1": //(emailSubject == "Subject1")
       //do acct request 
       break;
    case "Subject2": //(emailSubject == "Subject2")
       //do something else
       break;
    default:
       //do default 
}

Otherwise you should be using if/else

fredley
A: 

As mentioned, if/else is best for what you've got.

If, however, you were looking for actual whole subject lines, instead of words within subject lines, you could do something like:

var a = ["account request", "listserv application", "student organization webmaster transfer request"];
switch(a.indexOf(emailSubject)) {
  // ...
}
sje397
Subjects are dynamic but the conditional check is the common text for a given subject line. Typically a username is contained as well or potentially an id referencing something of another system.
Chris
You could mask relatively constant things like usernames and ids out (i.e. replace username with '%u' or something) before doing the above.
sje397
@sje seems like more trouble than its worth as this is merely a curiosity questio.
Chris
@Chris - understood. I found it interesting too.
sje397
+2  A: 

Constructs like this are usually crying out for polymorphism...

Play with it here: http://jsbin.com/utilu4/3

var mailHandlers = [

  {
    CanHandleEmail : function(email) {
      return email.subject.toLowerCase().indexOf("account request") >= 0;
    },

    HandleEmail : function(email) {
      alert("do acct req");
    }
  },

  {
    CanHandleEmail : function(email) {
      return email.subject.toLowerCase().indexOf("account pending removal for") >= 0;
    },

    HandleEmail : function(email) {
      alert("do account removal");
    }
  },

  {
    CanHandleEmail : function(email) {
      return email.subject.toLowerCase().indexOf("listserv application") >= 0;
    },

    HandleEmail : function(email) {
      alert("do listserv app");
    }
  },

  {
    CanHandleEmail : function(email) {
      return email.subject.toLowerCase().indexOf("student organization webmaster transfer request") >= 0;
    },

    HandleEmail : function(email) {
      alert("do webmaster xfer");
    }
  },

  {
    CanHandleEmail : function(email) {
      return true;
    },

    HandleEmail : function(email) {
      alert("do default");
    }
  }
];

function HandleEmail(email) {
  for(i=0; i< mailHandlers.length; i++) {
    if(mailHandlers[i].CanHandleEmail(email)){
      mailHandlers[i].HandleEmail(email);
      break;
    }
  }
};
joshperry
This is interesting. Very interesting. Although I am not sure I can execute this code in the environment where I am scripted it. It is within an application which takes and parses this code server side, but I will give this a try and regardless I learned something from it. Thanks for a great answer.
Chris
There were some syntax errors in that code, I hadn't tested it. It's fixed now.
joshperry
A: 

Just as a tip: wrap your code in a function and return the value of the match. (You don't have to use else in this case.) If you want to, you could return a code for the match (eg. an int) and use switch/case to perform the action.

FB55
That merely complicates the code by introducing pseudo enumeration if you will.
Chris