Author Topic: Using "or" operator  (Read 958 times)

Offline kwieto

  • Full Member
  • ***
  • Posts: 148
  • Karma: +3/-5
Using "or" operator
« on: February 20, 2017, 08:56:08 am »
I want to run a which is depending on the value of local defined variable, let say XYZ
This variable can have various states, let say that interesting for me are 1, 3, 7.
I want to build a condition that if XYZ is 1 or 3 or 7 then a code is executed.

It works with the syntax like:
Code: [Select]
]if XYZ == 1 or XYZ == 3 or XYZ == 7 then...
but maybe there is a simplier solution?

I've tried:
Code: [Select]
if XYZ == (1 or 3 or 7)
but this doesn't work.

Offline akbooer

  • Master Member
  • *******
  • Posts: 5180
  • Karma: +223/-67
  • "Less is more"
Re: Using "or" operator
« Reply #1 on: February 20, 2017, 09:33:58 am »
No, that doesn't work.  If in doubt, refer to the Lua Reference Manual: https://www.lua.org/manual/5.1/

However, a neater way to do this is:

Code: [Select]
local valid = {1, nil, 1, [7] = 1}   --- many ways to create this structure

if  valid[XYZ] then ...

You just have to be sure that XYZ is a number and not a string.  To be sure, you could write:

Code: [Select]
if  valid[tonumber(XYZ)] then ...

...or you could change the structure itself to be valid for strings also.
3x Vera Lite-UI5/Edge-UI7, 25x Fibaro, 23x TKB, 9x MiniMote, 2x NorthQ Power, 2x Netatmo, 1x Foscam FI9831P.
Razberry, MySensors Arduino, HomeWave, AltUI, DataYours, openLuup, ZWay, ZeroBrane Studio.

Offline kwieto

  • Full Member
  • ***
  • Posts: 148
  • Karma: +3/-5
Re: Using "or" operator
« Reply #2 on: February 21, 2017, 03:53:47 am »
Thanks, also for the reference documentation.

I still struggle to understand this part:

Code: [Select]
local valid = {1, nil, 1, [7] = 1} 
should I put here values in which I am interested, like:

Code: [Select]
local valid = {1, 3, 7}?

I don't know where to find that kind of structure in the reference documentation :(


Offline rge

  • Jr. Member
  • **
  • Posts: 92
  • Karma: +10/-0
Re: Using "or" operator
« Reply #3 on: February 21, 2017, 05:11:59 am »
The array proposal is to create an array where each entry lines up with one you are checking and gives you the answer.

Expanded fully, it looks like this:

local valid = {[1] = 1, [2] = nil, [3] = 1, [7] = 1}

You can put [test value] = answer for all the values you need to check (and for ones you don't specify, the answer will be nil).

To be honest, just use the OR statement for this small number of values, and only do something like this if you have a lot (say, more than one line of values in the IF statement).

Offline akbooer

  • Master Member
  • *******
  • Posts: 5180
  • Karma: +223/-67
  • "Less is more"
Re: Using "or" operator
« Reply #4 on: February 21, 2017, 05:21:06 am »
I don't know where to find that kind of structure in the reference documentation

It's here: Table Constructors

@rge is quite correct.  As I mentioned, there are many ways to create this structure.  Recall that any non-nil value is treated as a logical 'true', so it doesn't matter what value you give the table elements.

In full, both methods shown already are equivalent to:

Code: [Select]
local valid = {}
valid[1] = 1
valid[3] = 1
valid[7] = 1

Perhaps the clearest way to define what you need is, in fact:

Code: [Select]
local valid = {}
local states = {1,3,7}   -- put the numbers you want here
for _,x in ipairs(states) do
  valid[x] = 1
end

You should also, perhaps, take a look at the logical operators.  The original expression you wanted to try:

Code: [Select]
1 or 3 or 7
is always equal to 1.
3x Vera Lite-UI5/Edge-UI7, 25x Fibaro, 23x TKB, 9x MiniMote, 2x NorthQ Power, 2x Netatmo, 1x Foscam FI9831P.
Razberry, MySensors Arduino, HomeWave, AltUI, DataYours, openLuup, ZWay, ZeroBrane Studio.

Offline kwieto

  • Full Member
  • ***
  • Posts: 148
  • Karma: +3/-5
Re: Using "or" operator
« Reply #5 on: February 21, 2017, 05:34:59 am »
OK, i understand it better, but then shouldnt:

Code: [Select]
if  valid[tonumber(XYZ)] then ...
be more like
Code: [Select]
if  valid[tonumber(XYZ)] == 1 then ...[/quote]

?

Offline akbooer

  • Master Member
  • *******
  • Posts: 5180
  • Karma: +223/-67
  • "Less is more"
Re: Using "or" operator
« Reply #6 on: February 21, 2017, 06:18:14 am »
but then shouldnt:
...
be more like
...

Either will do...

Recall that any non-nil value is treated as a logical 'true', so it doesn't matter what value you give the table elements.
3x Vera Lite-UI5/Edge-UI7, 25x Fibaro, 23x TKB, 9x MiniMote, 2x NorthQ Power, 2x Netatmo, 1x Foscam FI9831P.
Razberry, MySensors Arduino, HomeWave, AltUI, DataYours, openLuup, ZWay, ZeroBrane Studio.

Offline rge

  • Jr. Member
  • **
  • Posts: 92
  • Karma: +10/-0
Re: Using "or" operator
« Reply #7 on: February 21, 2017, 08:44:32 am »
Recall that any non-nil value is treated as a logical 'true'

careful - nil and false are both false, anything else is true

Offline Slartibartfast

  • Hero Member
  • *****
  • Posts: 854
  • Karma: +378/-361
Re: Using "or" operator
« Reply #8 on: February 21, 2017, 08:54:13 am »
Comment from a non programmer.  :-\

I find the    ]if XYZ == 1 or XYZ == 3 or XYZ == 7 then...    version much easier to read.

Not so neat but easier to debug??
Devon UK 240V 50Hz
Now on Homeseer

Offline akbooer

  • Master Member
  • *******
  • Posts: 5180
  • Karma: +223/-67
  • "Less is more"
Re: Using "or" operator
« Reply #9 on: February 21, 2017, 08:59:53 am »
Yes, agreed.  Easier for just three values, but doesn't scale very well to more.

However, I do find the
Code: [Select]
if valid[x] then... syntax very readable once the variable is set up.
« Last Edit: February 21, 2017, 09:01:57 am by akbooer »
3x Vera Lite-UI5/Edge-UI7, 25x Fibaro, 23x TKB, 9x MiniMote, 2x NorthQ Power, 2x Netatmo, 1x Foscam FI9831P.
Razberry, MySensors Arduino, HomeWave, AltUI, DataYours, openLuup, ZWay, ZeroBrane Studio.

Offline Slartibartfast

  • Hero Member
  • *****
  • Posts: 854
  • Karma: +378/-361
Re: Using "or" operator
« Reply #10 on: February 21, 2017, 09:03:08 am »
I agree that a line with lots of OR functions spreading over multiple lines of code could get a bit cumbersome.
Devon UK 240V 50Hz
Now on Homeseer

Offline rge

  • Jr. Member
  • **
  • Posts: 92
  • Karma: +10/-0
Re: Using "or" operator
« Reply #11 on: February 21, 2017, 09:08:20 am »
Or if you have this pattern in multiple places, use a function that iterates over the list of things to check against:

isoneof  returns true if the first parameter matches any of the others, or false if not

Code: [Select]
local function isoneof (val, ...)
  for i,v in ipairs(arg) do
    if (val == v) then
      return true
    end
  end

  return false
end

So your line would become

Code: [Select]
if isoneof(XYZ, 1, 3, 7) then
Note - it is type sensitive, so you may still need the numeric conversion etc.

Offline akbooer

  • Master Member
  • *******
  • Posts: 5180
  • Karma: +223/-67
  • "Less is more"
Re: Using "or" operator
« Reply #12 on: February 21, 2017, 09:22:59 am »
I believe you mean:

Code: [Select]
local function isoneof (val, ...)
  for i,v in ipairs {...} do
    if (val == v) then
      return true
    end
  end

  return false
end
3x Vera Lite-UI5/Edge-UI7, 25x Fibaro, 23x TKB, 9x MiniMote, 2x NorthQ Power, 2x Netatmo, 1x Foscam FI9831P.
Razberry, MySensors Arduino, HomeWave, AltUI, DataYours, openLuup, ZWay, ZeroBrane Studio.

Offline Slartibartfast

  • Hero Member
  • *****
  • Posts: 854
  • Karma: +378/-361
Re: Using "or" operator
« Reply #13 on: February 21, 2017, 09:31:16 am »
Wow, see what I mean for us non programmers. the difference between () and {}    :P
Devon UK 240V 50Hz
Now on Homeseer

Offline kwieto

  • Full Member
  • ***
  • Posts: 148
  • Karma: +3/-5
Re: Using "or" operator
« Reply #14 on: February 21, 2017, 09:44:29 am »
@Slartibartfast
Some advantage of building up a function is that you can integrate it into startup lua, then call it every time you need from a various scenes, just defining the parameters according to the needs.

Then the code within a specific scene is more "elegant", I would say.
I am also not a programmer so I am a bit "blind" here, but anyhow I want to know better ways to do something if they are.