Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can the switch statement have more than one variable?

The question is based in all the languages that use the switch block (C++, C# PHP , Java , Python and so on). So is it possible to have something like this?

switch (var1, var2)
case  var1 = a:
    something
    break;
case var2 = b:
    something
    break;
case var1 = 0 ,var2 = 1
     etc...
like image 468
Bartlomiej Lewandowski Avatar asked Mar 25 '11 19:03

Bartlomiej Lewandowski


4 Answers

Python does not have a switch statement. The recommended alternative is using a chained if/else chain - which is what you ought to be using in your case anyway.

Another common idiom is using a map. And in your case you could use a tuple of (var1,var2) to match against results.

switch = {
   (1,2): lambda: ..,
   (3,4): lambda: ...,
}
switch[(var1,var2)]

I'm not sure this is commonly used, but at least it's possible.

like image 55
mario Avatar answered Sep 29 '22 00:09

mario


Yes/No.

No traditional language with a "switch" statement has this. It does exist in something called "pattern matching".

C#, Java, PHP, and Python do not support pattern matching (not completely sure about PHP, but I don't believe it does. Correct me if I'm wrong).

Here's an example in Haskell where pattern matching does exist. Pattern matching is in a lot of functional style languages.

function 1 _ = "first parameter has a one"
function _ 1 = "second parameter is a one"
function _ _ = "I don't know what crazy number you passed in"

When that function is called, the runtime/compiler/whoever checks it will see if the first function can be called. If it can, it returns that value. It then keeps going until it can find some match that works for the given parameters. The "_" is just a way of saying, "anything can be here, and I really don't care what it is so don't bind the value to a name". If I cared about the value, I could do:

function 1 a = "second parameter is " ++ (show a)

Now since it usually goes top-down (unlike the switch statement), this is more akin to an if/else than a switch statement which just jumps to the correct spot. It's just a very nice looking if/else. Also, if I reordered it so the most general case was at the top of the file, the other cases would be ignored.

You can also do something similar with templates, but that will only work at compile time.

like image 38
Jonathan Sternberg Avatar answered Sep 28 '22 23:09

Jonathan Sternberg


I think you can do arbitrary case matching in some languages like Haskell and ML. See Haskell Pattern Matching. The object in question is still a single object, but that object can be a tuple which contains an arbitrary number of objects.

An example given in the link is:

describeList :: [a] -> String
describeList list = 
  case list of
   []     -> "The list was empty"
   (x:xs) -> "The list wasn't empty: the first element was " ++ show x ++
             ", and there were " ++ show (length xs) ++
             " more elements in the list."
like image 34
Matthew Willis Avatar answered Sep 29 '22 00:09

Matthew Willis


CHILL allows it:

PROC (b board LOC,m move) EXCEPTIONS (illegal);
DCL starting square LOC:= b (m.lin_1)(m.col_1),
arriving square LOC:= b (m.lin_2)(m.col_2);
DO WITH m;
IF starting.status=free THEN CAUSE illegal; FI;
IF arriving.status/=free THEN
IF arriving.p.kind=king THEN CAUSE illegal; FI;
FI;
CASE starting.p.kind, starting.p.color OF
   (pawn),(white):
      IF col_1 = col_2 AND (arriving.status/=free
      OR NOT (lin_2=lin_1+1 OR lin_2=lin_1+2 AND lin_2=2))
      OR (col_2=PRED (col_1) OR col_2=SUCC (col_1))
      AND arriving.status=free THEN CAUSE illegal; FI;
      IF arriving.status/=free THEN
      IF arriving.p.color=white THEN CAUSE illegal; FI; FI;
   (pawn),(black):
      IF col_1=col_2 AND (arriving.status/=free
      OR NOT (lin_2=lin_11 OR lin_2=lin_12 AND lin_1=7))
      OR (col_2=PRED (col_1) OR col_2=SUCC (col_1))
      AND arriving.status=free THEN CAUSE illegal; FI;
      IF arriving.status/=free THEN
      IF arriving.p.color=black THEN CAUSE illegal; FI; FI;
   (rook),(*):
      IF NOT ok_rook (b,m)
      THEN CAUSE illegal;
      FI;
   (bishop),(*):
      IF NOT ok_bishop (b,m)
      THEN CAUSE illegal;
      FI;
   (queen),(*):
   IF NOT ok_rook (b,m) AND NOT ok_bishop (b,m)
     THEN CAUSE illegal;
like image 31
Otávio Décio Avatar answered Sep 29 '22 00:09

Otávio Décio