2

I would like to be able to call a function on a switch case statement but I can't seem to figure it out. Example:

switch(message.toLowerCase()) {
    // the startsWith would be an extension of the message.toLowerCase()
    // so that the case would be checking for message.toLowerCase().startsWith("pay")
    case startsWith("pay"):
        console.log(message)
        break
}

I have tried using case.function(), function(case), and case function(), but none of them work. Thanks!

Levi_OP
  • 945
  • 1
  • 9
  • 22

2 Answers2

6

Switch statements in JavaScript don't support pattern matching, they only do simple equality checks (the result of lowerCase() gets compared to the return value of startsWith(...) [if that function would exist]). You could do something like this though:

switch(true) {
  case message.toLowerCase().startsWith("pay"): // if this is true, the case matches
    console.log(message);
    break;
 }

You could also write some helpers to achieve more flexible pattern matching:

  const match = (...patterns) => value=> patterns.find(p => p.match(value))(value);
   const pattern = match => fn => Object.assign(fn, { match });
  const startWith = a => pattern(v => v.startsWith(a));

 match(
    startsWith("b")(console.error),
    startsWith("a")(console.log),
    startsWith("a")(console.error)
 )("abc")
Jonas Wilms
  • 132,000
  • 20
  • 149
  • 151
  • I would not use the first solution is because it is bascily just a if else statement, which is what I was trying to avoid by using a switch statement. – Levi_OP Jul 20 '20 at 19:59
  • 2
    what is a problem with `if-else`? – Jan Stránský Jul 20 '20 at 20:00
  • @jan the OP already seems to be aware of that option. Wether a switch statement or an if else if is cleaner is really a matter of personal preference. – Jonas Wilms Jul 20 '20 at 20:03
  • @JanStránský I am going to be having a lot of if-else's stacked on top of each other, and I want it to be very fast. From what I know switch statements are a lot faster then else-if because instead of checking every single option until you get to the right one, (with if-else), a switch statement will look at the value and jump straight to the correct case, which is much faster. – Levi_OP Jul 20 '20 at 20:06
  • This is wrong, in this case there won't be any difference. (and even in cases were it *could* matter, I doubt that this is even measurable) – Jonas Wilms Jul 20 '20 at 20:08
  • Well ok then. I guess I'll just use the if-else's. – Levi_OP Jul 20 '20 at 20:09
  • 1
    @Levi_OP Don't forget to save the `message.toLowerCase()` result into a variable. Otherwise you would need to execute this in every else-if statement, which would indeed make it slower. `const lowerMsg = message.toLowerCase()` (or override `message` if you don't need the original) then `if (lowerMsg.startsWith("play"))`, `else if (lowerMsg.startsWith("pause"))` – 3limin4t0r Jul 20 '20 at 20:12
2

One option is to use switch(true).

var m = message.toLowerCase()
switch(true) {
    case m.startsWith("pay"):
        console.log(message)
        break
}

Read the original thread for more details (e.g. that the case return value must be truely true, e.g. 1 would not work (but would work for if-else.

Also consider to use ordinary if-else, sometimes it might be more readable and maintainable than switch (and especially than this "non-standard" swith(true))

Also consider using regular expression. From the OP it is not really clear what you are looking for.

Jan Stránský
  • 1,671
  • 1
  • 11
  • 15