# Switch applying tests to forms

Is it correct that the Select equivalent of Cases is missing for Switch?

I mean a function switch[conditionFunction,form1,value1,form2,value2,...]. Where conditionFunction would be a function that evaluates to True or False on the various forms, and switch would return the first value for which conditionFunction[form] evaluates to True.

What should I be using for this? If nothing pre-exists, what would be the best way to implement this.? (And why is this missing if we do have both Select and Cases by default?)

• Perhaps Whichis the function you're looking for. – Ulrich Neumann Nov 4 '18 at 16:42
• @UlrichNeumann, no, I don't want to have repeat the same test to be applied to all the forms. I do think that it is easy to write what I want using Which, with which I was already familiar, so I should have mentioned it in my question anyway. – Kvothe Nov 4 '18 at 17:14
• Which repeats testing until the first True is detected! – Ulrich Neumann Nov 4 '18 at 17:50
• Sorry that comment wasn't too clear. I meant since the test would be the same I don't want to have to type it for every entry just changing the argument. (That's better for readability and not just to save on the typing.) – Kvothe Nov 5 '18 at 9:43

switch // Attributes = { HoldRest };

switch[foo_, spec__] /; EvenQ @ Length @ Unevaluated[spec] :=
Which @@ MapAt[foo, Hold[spec], ;; ;; 2]


This way we will not evaluate foo with forms present after the correct one.

switch[True & @* Echo, a, 1, b, 2, c, 3]


>> a

1

• Thanks, with SetAttributes[switch,HoldAll] if we want it to behave as Which right? (Otherwise the forms are already evaluated before they are taken as input.) – Kvothe Nov 5 '18 at 9:41
• @Kvothe correct, I didn't do this because I was not sure if holding them makes sense, but now I think it does. See the edit. I've also included arg length check. – Kuba Nov 5 '18 at 12:46

Maybe this?

switch[f_, forms_, values_] := Which @@ Riffle[f /@ forms, values]


Usage example:

switch[# == "c" &, {"a", "b", "c", "d", "e"}, {1, 2, 3, 4, 5}]


However, this evaluates f over all forms , although it could also short-circuit.