"IF THEN - $SELECT - $CASE" - What is the best way?
Hi all,
I'm wonder what could be the best way convert the sentence "Switch" C# into Cache code.
int caseSwitch = 1; switch (caseSwitch) { case 1: Console.WriteLine("Case 1"); break; case 2: Console.WriteLine("Case 2"); break; default: Console.WriteLine("Default case"); break; }
My first attempt was:
set caseSwith = 1 if (caseSwith = 1) { w "Case 1" } else { if (caseSwith = 2) { w "Case 2" } else { w "Default case" } }
Maybe, for complex conditions, it should be the best option, however I've used the $SELECT command
set caseSwith = 1 w $SELECT(caseSwith=1:"Case 1",caseSwith=2:"Case 2",1:"Default case")
It seems the best option for simple sentence (one line and clear)
Other options is using the $CASE command
set caseSwith = 1 w $CASE(caseSwith, 1:"Case 1",2:"Case 2",:"Default case")
so, it is easier because it is checking only one variable to evaluate the condition.
My question is, what should be the best way for complex conditions?
set val1 = 1 set val2 = 2 set val3 = 3 if ((val1>=3)&&(val1<=9)) { if (val2=0) { w "Condition 1" } else { if (val2>0) { w "Condition 2" } } } else { if (val2=1) { if (val3<3) { w "Condition 3" } else { w "Condition default 1" } } else { if ((val2>1) && (val2<9)) { w "Condition 4" } else { w "Condition default 2" } } }
As you see, it so complex because the condition is linked to 3 variables.
Trying to use $SELECT with this example
set val1 = 1 set val2 = 2 set val3 = 3 w $SELECT((val1>=3)&&(val1<=9): $SELECT(val2=0:"Condition 1",val2>0:"Condition 2"),val2=1:$SELECT(val3<3:"Condition 3",1:"Condition default 1"),val2'=1:$SELECT((val2>1) && (val2<9):"Condition 4",1:"Condition default 2"))
The line is longer and quite complicated to read
I haven't used $CASE because it affect to more than one variable.
So I don't want to create hundreds line of IF THEN conditions, but I want to have a clear code and easy for maintenance.
Please comment on how do you would solve this problem
If you use the IF style, I suggest you also consider using the ELSEIF clause. See doc here.
Then, according your opinion, for complex conditions the best way is use IF ELSEIF instead of $SELECT or other similar
That's right
I like it. I think this is the cleanest way to solve my problem.
Thanks a lot
but remember about performance ...
ClassMethod Test(val = 3) [ ProcedureBlock = 0 ]{
s:'$d(^||addr) ^||addr(1)=1, (^(2),^(8),^(9))=289, ^(3)=3
d @("t1case" _ $g( ^||addr( val ) ) ) Q
t1case1 w !, "Case 1" Q
t1case3 w !, "Case 3" Q
t1case289 w !, "Case 2 or 8 or 9" Q
t1case w !,"Case default" Q
}
/// Local variable with indirection
ClassMethod Test2(val = 3) [ ProcedureBlock = 0 ]{
s:'$d(addr) addr(1)=1, (addr(2),addr(8),addr(9))=289, addr(3)=3
d @( "t2case"_$g( addr( val ) ) ) Q
t2case1 w !, "Case 1" Q
t2case3 w !, "Case 3" Q
t2case289 w !, "Case 2 or 8 or 9" Q
t2case w !,"Case default" Q
}
/// Without indirection
ClassMethod Test3(val = 3) [ ProcedureBlock = 0 ]{
if val=1 w !, "Case 1" Q
if val=3 w !, "Case 3" Q
if (val=2)!(val=8)!(val=9) w !, "Case 2 or 8 or 9" Q
w !,"Case default"
}
/// Process private global without indirection
ClassMethod Test4(val = 3) [ ProcedureBlock = 0 ]{
s:'$d(^||addr) ^||addr(1)=1, (^(2),^(8),^(9))=289, ^(3)=3
d $case($g(^||addr(val)),1:t4case1,289:t4case289,3:t4case3,:t4case)
Q
t4case1 w !, "Case 1" Q
t4case3 w !, "Case 3" Q
t4case289 w !, "Case 2 or 8 or 9" Q
t4case w !,"Case default" Q
}
/// Local variable without indirection
ClassMethod Test5(val = 3) [ ProcedureBlock = 0 ]{
s:'$d(addr) addr(1)=1, (addr(2),addr(8),addr(9))=289, addr(3)=3
d $case($g(addr(val)),1:t5case1,289:t5case289,3:t5case3,:t5case)
Q
t5case1 w !, "Case 1" Q
t5case3 w !, "Case 3" Q
t5case289 w !, "Case 2 or 8 or 9" Q
t5case w !,"Case default" Q
}
ClassMethod Run() {
s repeat = 1000
s ts = $zh for i=1:1:repeat { d ..Test( $r(10)+1 ) } s t1 = ( $zh - ts )
s ts = $zh for i=1:1:repeat { d ..Test2( $r(10)+1 ) } s t2 = ( $zh - ts )
s ts = $zh for i=1:1:repeat { d ..Test3( $r(10)+1 ) } s t3 = ( $zh - ts )
s ts = $zh for i=1:1:repeat { d ..Test4( $r(10)+1 ) } s t4 = ( $zh - ts )
s ts = $zh for i=1:1:repeat { d ..Test5( $r(10)+1 ) } s t5 = ( $zh - ts )
w !, "do @( ^||addr() ) : ", t1
w !, "do @( addr() ) : ", t2
w !, "if val=case Q : ", t3
w !, "do $case( ^||addr() ) : ", t4
w !, "do $case( addr() ) : ", t5
}
Output:
Suppose there is such a code:
In this case
For this particular case, I suggest using a transition table, for example:
Of course, you can modify the example to call procedures, functions, class methods, etc.
Good point !!!!
Hi, Vitaliy!
1,2,3 - fix it and update, thank you; 4 - agree with you
updated
There are one error in the Test5 method: t4case* -> t5case*
Thank you again! Updated
So, in order.
There is no limit to perfection.
Better then d:(v=2)!(v=8)!(v=9) t3case289 q
Can also speed up, abandoning the indirect:
But the quickest option is if/elseif/else, since here is used inline-call, and not external-call.
http://localhost:57772/csp/docbook/DocBook.UI.Page.cls?KEY=RCOS_fselect
http://localhost:57772/csp/docbook/DocBook.UI.Page.cls?KEY=RCOS_fcase
Hi,
I won't claim this is an answer, because it's not quite the same and people may object to the structure, but here is one solution that is used quite a lot in code I look after. Basically, a subroutine is called and then tests are done and a Quit is used to drop out when a match is found. Often used for validation, something like this that returns a result in the zER variable:
V1 ; Validate ORGC
S ORG=zORG D WC2^hZUTV I zER'="" Q
I IPACC<9,'$D(^hIW(WAID)) S zER="No details set up for ward" Q
D WARDON^hILO1 I LOCK S zER="Ward in use" Q
VQ2 Q
Apologies for the old-fashioned code! However, you can see each test can be quite complex and using lots of variables, but it is easy to understand as long as you expect the structure to work that way.
This is very similar to the "clean code" solution of making the whole thing into a function that returns a value:
Of course there are probably as many answers as there are Cache programmers! :-)
You might want to restructure your multiple conditions per $case in a somewhat unusual fashion like this
Obviously, a complex condition cannot produce simple code. I do this in that way:
It's more clear and readable.
Social networks
InterSystems resources
Log in or sign up
Log in or create a new account to continue
Log in or sign up
Log in or create a new account to continue
Log in or sign up
Log in or create a new account to continue