Expression language switch() upgrade

Upgrade expression switch function to allow expressions in the case statements, possibly in the form of "one sided" comparisons. The function would plug in the "switched value" for missing numeric terms preceding the following operators (>, >=, <, <=, =, !=, ), and (!, ^, %, *, /, +, -, &, |, xor, if followed by one of the earlier operators and another expression) in the case condition evaluation. The function should return the first true value.

I would expect the following example to return 'two'.


5 && <10, //case 1
!=3, //case 2
0, // case 3
'one', //result 1
'two', //result 2
'three', //result 3
'none') //default

This was prompted by the following example. Is there a better way using existing functions?

if({Root Container.Compass.Meter.value}>337.5, 'N', if({Root Container.Compass.Meter.value}>292.5, 'NW', if({Root Container.Compass.Meter.value}>247.5, 'W', if({Root Container.Compass.Meter.value}>202.5, 'SW', if({Root Container.Compass.Meter.value}>157.5, 'S', if({Root Container.Compass.Meter.value}>112.5, 'SE', if({Root Container.Compass.Meter.value}>67.5, 'E', if({Root Container.Compass.Meter.value}>22.5, 'NE','N'))))))))

Sorry, from a language perspective, this is definately a no-go. Sounds good in english, perhaps, but definately not as part of the expression language.

BTW - The way I’d see this happening is with an expression like lookup that, if it didn’t find an exact match, matched the closest or next value. This is like VLOOKUP in Excel with range_lookup set to TRUE.

Makes sense - I had a feeling it wouldn’t work well in a parser. Other languages have more keywords and syntax to support it (;s, CASE, BETWEEN, IS, etc). What about creating an explicit placeholder like {selected_value}, which would be the evaluated expression of the first argument of the switch function? Although, realistically, that wouldn’t save you much in 90+% of the cases.

lookup would accomplish what I’m after. It would be nice to have the option of returning either the first, or closest value. I don’t care if it’s a parameter or separate functions. I’d recommend that it be able to take in a DataSet as well as a list of values.

Hey Guys,

I think I have a workaround. If you use binEnum() in addition to the switch, you could get the result you want. If you look it up, binEnum does:[quote]This function, whose name stands for “binary enumeration”, takes a list of booleans, and returns the index of the first parameter that evaluates to true. For example:
…returns 2 ( the index of the true parameter)[/quote]If you use them together, you could get the index of the first true statement, and then index that (with the switch) to some other value. I don’t have FactoryPMI installed right now to test it, but I believe you can use expressions in binEnum.switch( binEnum({value}>5 && {value}<10, {value}!=3, {value}> 0) 1,2,3, 'one', //result 1 'two', //result 2 'three', //result 3 'none') //default While I’m thinking about it, could we do a different form of the binEnum() that is more like the switch statement? It could take in an even number of args and instead of enumerating, return the “result” that matches the first true value.

Other than that, you could just use nested if statements. It’s not pretty, but it’ll work.

if({value}>5 && {value}<10, //case 1 "one", //result 1 if({value}!=3, //case 2 "two", //result 2 if({value}>0, //case 3 "three", //result 3 "none" //default ) ) )

1 Like

Robert: Brilliant! Using binEnum as the switch value is a great idea.

Nice one! That’ll have to make its way into the switch function documentation tips at some point.

I still don’t see it in the manual… yet.

Great tip though! Hail to searches yielding easter eggs.

1 Like