If that were going to work, I'd expect it to be equivalent to "if ... and ... and ..." and not "if ... or ... or ...". But no, it doesn't work in Lua anyway.
I believe your second code snippet is actually equivalent to
if (class == NN) then
if (FF == true) then
if (PP == true) then
-- then
end
elseif (PP == false) then
-- then
end
else
if (FF == false) then
if (PP == true) then
-- then
end
elseif (PP == false) then
-- then
end
end
because Lua would interpret each equality operator left-associatively, and the result of equality operators is always 'true' or 'false'.
A better shorthand for your multiple-or would be a switch statement, like
switch (class)
case NN
case FF
case PP
// then...
but Lua doesn't have switch statements anyway.
So, you're stuck with the verbose version. If you have to access the var 'class' many times, though, you can at least make sure it's local for faster access; that is, if it wasn't defined inside or an argument to your function, then do "local class = class" to local-ize the upvalue.
Edit: another way you could accomplish that, if your list of options is relatively static, would be something like:
local values = {}
values[NN] = true
values[FF] = true
values[PP] = true
...
if (values[class]) then
But that requires you to update "values" any time the pointers "NN", "FF" or "PP" change.
if you need to do that multiple times, or have some other reason to do it quickly, you could always set up another value wherever class gets assigned, like this:
If you really want a shorter syntax (at least different, anyway) you can use Lua's metatable functionality to do a comparison like:
if [a, b, c] == [1, 2, 3] then return end
But this would be a bad idea.
Edit: Against my better judgment, I have implemented it for you here:
Usage
if Set.new({"Rogue"}) == Set.new({"Rogue", "Shaman", "Warrior"}) then
print("true")
else
print("false")
end
The Code
Set = {}
Set.mt = {}
function Set.new(t)
local set = {}
setmetatable(set, Set.mt)
for i,v in ipairs(t) do set[i] = v end
return set
end
Set.mt.__eq = function(a, b)
local l = (table.maxn(a) >= table.maxn(b)) and a or b
for _,v in ipairs(l) do
if a[1] == v then return true end
end
return false
end
I sure hope no one takes me out back and shoots me.
No programming language in the world will let you write a conditional like that. Even if one did, this would not do what you expect. Logically, it would return true only if NN, FF, and PP are all equal to class (e.g. class == NN and class == FF and class == PP).
if Set.new({"Rogue"}) == Set.new({"Rogue", "Shaman", "Warrior"}) then
Gotta nip this one in the bud right now. Do *NOT* get in the habit of using tables like this, it is very wasteful and only creates needless garbage to be collected. Use the and/or chaining instead, or if you have a very large set of possible values...
Lua doesn't have C-style logic operations by default. It does have and/or/not but they have other behavior which is both elegant for some purposes and useless for what you want to do. In essence and/or mimick what C does with the "conditional ? return a : return b" behavior, which isn't a clean logic operation, but conditional mixed with return behavior.
There is nothing wrong with doing
if class == "A" or class =="B" or class=="C" then
and if you want to go fancy, the lua way of solving this is basically was tek posted with table indexing.
If you want to twist your spine for this you can use "bit" logic masked as integer operations.
e.g. A=1, B=2, C=4, D=8, E=16
set A..E if class =="A" then...
then do
if nClass = A+B then -- exactly A and B are present
if nClass < A+B+C then -- any of A,B,C, but nothing else is present
etc
You can also use luas bit logic extension which will give you faithful bit logic handling. (bit.bor, bit.band etc)
Both of these only make sense if you frequently look for very specific combinations of things. Else just go with the if or the table.
There is a way not to repeat "test", without using any table but it is still more expensive than combined "or".
function isContainedIn(v, ...)
local n = select('#', ...)
for i = 1, n do
if v == select(i, ...) then
return true
end
end
end
<...>
if isContainedIn(foo, NN, FF, PP) then
-- Do it
end
Gotta nip this one in the bud right now. Do *NOT* get in the habit of using tables like this, it is very wasteful and only creates needless garbage to be collected. Use the and/or chaining instead, or if you have a very large set of possible values...
Yeah. I should have thrown a disclaimer in my code. My only goal was to get the syntax as I could to his and what I wrote ends up being much closer than properly defining the tables as locals. There are too many things wrong with my proposed code snippet to count.
Instead of writing
can I write it like this?
All answers appreciated.
http://www.lua.org/manual/5.1/
http://www.lua.org/pil/
If that were going to work, I'd expect it to be equivalent to "if ... and ... and ..." and not "if ... or ... or ...". But no, it doesn't work in Lua anyway.
I believe your second code snippet is actually equivalent to
because Lua would interpret each equality operator left-associatively, and the result of equality operators is always 'true' or 'false'.
A better shorthand for your multiple-or would be a switch statement, like
but Lua doesn't have switch statements anyway.
So, you're stuck with the verbose version. If you have to access the var 'class' many times, though, you can at least make sure it's local for faster access; that is, if it wasn't defined inside or an argument to your function, then do "local class = class" to local-ize the upvalue.
Edit: another way you could accomplish that, if your list of options is relatively static, would be something like:
But that requires you to update "values" any time the pointers "NN", "FF" or "PP" change.
local value
value = class == NN or class == FF or class == PP
then you can access it later by just checking:
if value then
But this would be a bad idea.
Edit: Against my better judgment, I have implemented it for you here:
Usage
The Code
I sure hope no one takes me out back and shoots me.
Gotta nip this one in the bud right now. Do *NOT* get in the habit of using tables like this, it is very wasteful and only creates needless garbage to be collected. Use the and/or chaining instead, or if you have a very large set of possible values...
<script src="http://gist.github.com/48303.js"></script>
This wouldn't work either?
|| is the 'or' operator, right?
There is nothing wrong with doing
if class == "A" or class =="B" or class=="C" then
and if you want to go fancy, the lua way of solving this is basically was tek posted with table indexing.
If you want to twist your spine for this you can use "bit" logic masked as integer operations.
e.g. A=1, B=2, C=4, D=8, E=16
set A..E if class =="A" then...
then do
if nClass = A+B then -- exactly A and B are present
if nClass < A+B+C then -- any of A,B,C, but nothing else is present
etc
You can also use luas bit logic extension which will give you faithful bit logic handling. (bit.bor, bit.band etc)
Both of these only make sense if you frequently look for very specific combinations of things. Else just go with the if or the table.
It doesn't matter whether you spell the or operator "or" or "||". This isn't going to work.
If you can't stand typing "class" three times each time you need to do the test, write it like this:
Yeah. I should have thrown a disclaimer in my code. My only goal was to get the syntax as I could to his and what I wrote ends up being much closer than properly defining the tables as locals. There are too many things wrong with my proposed code snippet to count.