Srdjan M.
Srdjan M.

Reputation: 3405

Lua, if statement idiom

local a = {}
local b = {}

local c,d = (a~=nil) and 1,1 or 0,0 -- prints "1 1"

local c,d = (a==nil) and 1,1 or 0,0 -- prints "false 1"

print(c,d)

I get why this happens. Is there a way to print "0 0"?

Upvotes: 2

Views: 1939

Answers (3)

Nicol Bolas
Nicol Bolas

Reputation: 474436

If you really want to do this in the most compact way possible, you can create a function to do it. I generally only have it take one parameter per condition, but if you absolutely need one that handles multiples, there are two ways to do it.

Option #1: Take tables:

function iff(cond, tbl1, tbl2)
  if(cond) then
    return unpack(tbl1)
  else
    return unpack(tbl2)
  end
end

Obviously, this requires that you always pass tables. If you only need single values, then you'd need a second version of the function. That's preferable to adding conditional logic based on types, thus slowing your code down.

Option #2: Variadic:

--Number of parameters ought to be even.
--The first half are returned if the condition is true,
--the second half if it is false.
function iff(cond, ...)
  if(cond) then
    return ... --Yes, you're returning all of them, but the user shouldn't be trying to take more than the first half.
  else
    return select((select("#", ...)) / 2, ...)
  end
end

Upvotes: 1

Srdjan M.
Srdjan M.

Reputation: 3405

As pointed out by "Paul Kulchenko" in his last sentence, I ended up adding two idioms...

local a = {}
local b = {}

local c,d = (a~=nil) and 1 or 0, (a~=nil) and 1 or 0 -- prints "1 1"

local c,d = (a==nil) and 1 or 0, (a==nil) and 1 or 0 -- prints "0 0"

print(c,d)

Upvotes: 0

Paul Kulchenko
Paul Kulchenko

Reputation: 26794

Is there a way to print "0 0"?

No, because and or expression always returns one result and the results you see are probably not for the reason you think they are.

local c,d = (a~=nil) and 1,1 or 0,0 -- prints "1 1"

This is calculated as ((a~=nil) and 1),(1 or 0),0. The first expression returns 1, the second (1 or 0) returns 1 and the last one is ignored (as you have two variables on the left side and three expressions on the right).

local c,d = (a==nil) and 1,1 or 0,0 -- prints "false 1"

This is calculated in a similar way, except (a==nil) is false and that's why you get the second result.

To do what you want, you'll need to split it into two expressions: one for c and one for d.

Upvotes: 5

Related Questions