Conditionally filling tables

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Conditionally filling tables

Alexander Gladysh
Hi, all!

I need to create table (array), conditionally filled with elements.
Something like this (in pseudocode):

t =
{
  A,
  B,
  if Condition1 then C else D end,
  if Condition2 then E else nil end,
  F
}

Problem is that second 'if' would generate gap in array if Condition2
is false. Of course I can iterate over array after its creation, and
close the gaps, which I would like to avoid.

Furthermore, (looks like) Lua syntax does not allow if statements to
appear inside table constructor, so I would have to use helper
function.

local iff = function(b, l, r) if b then return l else return r end end;
t =
{
  A,
  B,
  iff(Condition1, C, D),
  iff(Condition2, E, nil),
  F
}

I see another way with manually specifying indexes in array like this:

local index = 1
local nextindex = function()
  local oldindex = index
  index = index + 1
  return oldindex
end

local iff = function(b, l, r) if b then return l else return r end end;
local iffc = function(b, l, r)
  if b then
    if l then index = index + 1 end
    return l
  else
    if r then index = index + 1 end
    return r
  end
end

t =
{
  [nextindex()] = A,
  [nextindex()] = B,
  [nextindex()] = iff(Condition1, C, D),
  [index] = iffc(Condition2, E, nil),
  [nextindex()] = F
}

In this way, if branch with nil is selected, index is not incremented,
and nil array entry gets overridden with next element (F in the
example). (And if there is no next element, then it would be discarded
by Lua itself, so it is ok.)

While such approach looks suitable for my machine-generated case, I
would like to find some more user-friendly technique.

Any advices?

Thanks in advance,
Alexander.


Reply | Threaded
Open this post in threaded view
|

Re: Conditionally filling tables

Asko Kauppi

I've used 'false' in such cases, as table hole fillers.

Condition1 and C or D,
Condition2 and E or false,

Simple, but not perfect..


Alexander Gladysh kirjoitti 10.3.2006 kello 8.59:

Hi, all!

I need to create table (array), conditionally filled with elements.
Something like this (in pseudocode):

t =
{
  A,
  B,
  if Condition1 then C else D end,
  if Condition2 then E else nil end,
  F
}

Problem is that second 'if' would generate gap in array if Condition2
is false. Of course I can iterate over array after its creation, and
close the gaps, which I would like to avoid.

Furthermore, (looks like) Lua syntax does not allow if statements to
appear inside table constructor, so I would have to use helper
function.

local iff = function(b, l, r) if b then return l else return r end end;
t =
{
  A,
  B,
  iff(Condition1, C, D),
  iff(Condition2, E, nil),
  F
}

I see another way with manually specifying indexes in array like this:

local index = 1
local nextindex = function()
  local oldindex = index
  index = index + 1
  return oldindex
end

local iff = function(b, l, r) if b then return l else return r end end;
local iffc = function(b, l, r)
  if b then
    if l then index = index + 1 end
    return l
  else
    if r then index = index + 1 end
    return r
  end
end

t =
{
  [nextindex()] = A,
  [nextindex()] = B,
  [nextindex()] = iff(Condition1, C, D),
  [index] = iffc(Condition2, E, nil),
  [nextindex()] = F
}

In this way, if branch with nil is selected, index is not incremented,
and nil array entry gets overridden with next element (F in the
example). (And if there is no next element, then it would be discarded
by Lua itself, so it is ok.)

While such approach looks suitable for my machine-generated case, I
would like to find some more user-friendly technique.

Any advices?

Thanks in advance,
Alexander.


Reply | Threaded
Open this post in threaded view
|

Re: Conditionally filling tables

Alexander Gladysh
> I've used 'false' in such cases, as table hole fillers.
>
> Condition1 and C or D,
> Condition2 and E or false,
>
> Simple, but not perfect..

Thanks, but 1) this still require post-processing of the table and 2)
what if I'd want to create array of bools?

Alexander.


Reply | Threaded
Open this post in threaded view
|

RE: Conditionally filling tables

Marius Gheorghe
In reply to this post by Alexander Gladysh
> Any advices?

You could try the following (not fully tested and using 5.0 syntax):
function iff(cond, a, b)
  if cond then
    return a
  else
    return b
  end
end

function newtable(...)
  local result = {}

  for i = 1, table.getn(arg) do
    local v = arg[i]

    if v ~= nil then
      table.insert(result, v)
    end
  end

  return result
end

-- Usage
A, B, C, D, E, F = 1, 2, 3, 4, 5, 6
Cond1 = true
Cond2 = false

t = newtable(A, B, iff(Cond1, C, D), iff(Cond2, E, nil), F)

for i, v in ipairs(t) do
  print(i, v)
end
print()

Cond1 = false
Cond2 = true

t = newtable(A, B, iff(Cond1, C, D), iff(Cond2, E, nil), F)

for i, v in ipairs(t) do
  print(i, v)
end
print()

Marius Gheorghe

Reply | Threaded
Open this post in threaded view
|

Re: Conditionally filling tables

Adrian Sietsma
In reply to this post by Alexander Gladysh
Alexander Gladysh wrote:
I've used 'false' in such cases, as table hole fillers.

Condition1 and C or D,
Condition2 and E or false,

Simple, but not perfect..


Thanks, but 1) this still require post-processing of the table and 2)
what if I'd want to create array of bools?

local nothing = {}

t = {
	(Condition1 and C) or (not Condition1 and D),
	(Condition2 and E) or (not Condition2 and nothing) ,
    }

...

local j = 1
for i = 1, table.maxn(t) do
   local v = t[i]
   if v == nil then break end
   if v ~= nothing then
      t[j], j = v, j+1
   end
end


Adrian