Switch()
Description
FUNCTION: switch(string[,pattern1,result1]...[,default])
This function attempts to wildcard match string against each pattern from left to right. The first pattern that matches has its corresponding result evaluated. If no pattern is matched and a default argument is given, default is evaluated. This function expects at least two arguments (string and default). If an odd number of arguments is given, then there is no default argument.
In addition to wildcard matching, numeric matches are performed using patterns prefixed with > and < symbols. See the examples section for clarification. In TinyMUX this comparison is integer only and will work with any integer-prefixed string. In PennMUSH this comparison is floating and will only be numerical comparison if both the string and pattern contain valid floating number values. If not, PennMUSH will perform string comparison instead.
Related topics: case(), @switch, ifelse(), match().
Examples
> say switch(c,*a*,A,*b*,B,*c*,C,*d*,D,E) You say "C" > say switch(f,*a*,A,*b*,B,*c*,C,*d*,D,E) You say "E" > say switch(cab,*a*,A,*b*,B,*c*,C,*d*,D,E) You say "A" > say switch(f,*a*,A,*b*,B,*c*,C,*d*,D) You say "" > say switch(10,>4,yes,no) You say "yes" > say switch(10,<4,yes,no) You say "no" > say switch(5.1,<5Z,yes,no) You say "yes" <-- PennMUSH does this You say "no" <-- MUX does this
Nifty Tricks
There's many small tricks one can use with switch(). Get clever!
Nifty Trick #1
Often you'll want to see if an item is in a list. If it is, do one thing. If not, do another thing. You can more or less do this in one shot with switch(), assuming that one thing doesn't contain a delimiting character (typically a space):
The generic code looks like this:
switch(%blist%b,*%bitem%b*,if found code,if not found code)
You can extend the code to include more things to look for if previous items were not found.
Example:
> th switch(%bthis is a list of stuff%b,*%blist%b*,Found word,Not found) Found word > th switch(%bthis is a list of stuff%b,*%bpie%b*,Pie found,*%blist%b*, [Pie not found, but list was],Not found) Pie not found, but list was
Nifty Trick #2
Sometimes you'll want to know if string is completely empty. No characters. Zip. An easy method of detecting this is to specify a pattern that contains nothing.
Example:
> th switch(Blank?,,String is blank,String is not blank) String is not blank > th switch(,,String is blank,String is not blank) String is blank
If this is all you were doing, using case() would be best because it doesn't have the overhead of wildcard matching. However, often you'll want to detect a blank pattern argument in addition to other operations that can be done with switch().
If you wanted to detect an empty list while looking for a certain item in the list...
switch(%bsome list%b,,List is empty!,*%bsome%b*,Something was found,Nothing found)
Nifty Trick #3
Suppose you want to list more than one wildcard pattern at a time, and you know that | will never occur in the string to match the first one.
Then code such as this can be used:
switch(string1|string2,pattern1|pattern2, Both matched,One or both did not match)
Or being more fancy:
switch(string1|string2,pattern1|pattern2, Both matched,pattern1|*,Only pattern1 matched, *|pattern2,Only pattern2 matched, neither matched)
You can even use this in conjunction with the above tricks! ... But it looks ugly, so it is omitted here.
Nifty Trick #4
What if I want to compare a number, and if the comparison fails, match a string? This only works on MUX with integers:
switch(number|string,>value, Number is greater than value, *|pattern,String matches pattern, Default case)
Or maybe I want to make sure a number is within certain bounds and a string matches a certain pattern?
switch(number|string,<lower value,Too low, >upper value,Too high, *|pattern,Looks good,Didn't match)
By combining these methods and coining clever wildcard patterns of your own, you can compact, simplify, and speed up a good deal of code. It's not always a winning situation, as you can still manage to expand, obfuscate, or slow down the code if these methods are taken to the extreme, but sometimes such may be done to fight a low function_invocation_limit.
Nifty Trick #5
It's very common to want to perform a general series of tests (not just matching one value to a set of strings) and return different values. A common idiom is:
switch(1,sometest1,result1,sometest2,result2,...,default result)
Where sometest1, sometest2, etc. are function calls that return 1 if true or successful. This switch compares the value '1' against each test in turn until one succeeds. Another similar idiom uses '0' and compares until a test fails.
Be creative!