indexOf within Switch

Leaf picture Leaf · Mar 9, 2014 · Viewed 16.6k times · Source

I have a Javascript-based bot for a Xat chatroom which also acts as an AI. I've recently decided to redo the AI part of it due to it becoming an absolutely massive chain of else if statements, becoming nearly impossible to work with.

I did some research and came up with a new idea of how to handle responses. I'll give you the code segment first:

function msgSwitch(id,msgRes) {
var botResponse = [];

switch (msgRes) {
  case (msgRes.indexOf("hi") !=-1):
    botResponse.push("HELLO. ");
  case (msgRes.indexOf("how are you") !=-1):
    botResponse.push("I AM FINE. ")
  case (msgRes.indexOf("do you like pie") !=-1):
    botResponse.push("I CAN'T EAT. THANKS, ASSHAT. ")
  default:
    respond (botResponse);
    spamCount(id);
    break;
}

}

The idea here is to check msgRes (the user's input) and see how many cases it matches. Then for each match, it'll push the response into the botResponse array, then at the end, it'll reply with all the messages in that array.

Example

User Msg: Hi! How are you?

msgRes: hi how are you

Bot Matches:

hi > pushes HELLO. to array

how are you > pushes I AM FINE. to array

Bot Responds: HELLO. I AM FINE.

This in turn saves me the trouble of having to write an if for each possible combination.

However, after looking into it some more, I'm not sure if it's possible use indexOf inside of a switch. Does anyone know of a way around this or have a better idea for handling responses in the same manner?

EDIT:

To Avoid the XY Problem (To clarify my problem)

I need a clean alternative to using a massive chain of else if statements. There are going to be hundreds of word segments that the bot will respond to. Without the ability for it to keep searching for matches, I'd have to write a new else if for every combination.

I'm hoping for a way to have it scan through every statement for a match, then combine the response for each match together into a single string.

EDIT 2: I should also add that this is being ran on Tampermonkey and not a website.

Answer

dandavis picture dandavis · Mar 9, 2014

you just need to compare to true instead of msgRes (since cases use === comparison), and use break to prevent the annoying fall-though of the switch behavior:

function msgSwitch(id,msgRes) {
 var botResponse = [];

 switch (true) {
  case (msgRes.indexOf("hi") !=-1):
    botResponse.push("HELLO. "); break;
  case (msgRes.indexOf("how are you") !=-1):
    botResponse.push("I AM FINE. "); break;
  case (msgRes.indexOf("do you like pie") !=-1):
    botResponse.push("I CAN'T EAT. THANKS, ASSHAT. "); break;
  default:
    respond (botResponse);
    spamCount(id);
    break;
 }

}

This is a perfectly valid logical forking pattern, known as an "overloaded switch". A lot of folks might not realize that each case: is an expression, not just a value, so you could even put an IIFE in there if needed...