Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Iterate through vars without a index?

I set some vars like this:

local var1Age = 10
local var2Age = 20
local var3Age = 30

Now I want to iterate them with a loop like this:

for i=1, 3 do
    if var..i..Age >= 21 then
        print("yep")
    end
end

I can't change the vars, or create a table instead. Is it possible somehow with this vars?

Edit: I could do something like this:

if var1Age >= 21 then
    print("yep")
end
if var2Age >= 21 then
    print("yep")
end
if var3Age >= 21 then
    print("yep")
end

But I have ~50 vars like that. That's why I search a way to do it with a loop.

Edit2: The vars are set by a class I can't change, so I can't change the way the vars are set. For example I can't set the vars like this:

local varAge = {}
varAge[1] = 10
varAge[2] = 20
varAge[3] = 30

Edit3: The class saves the vars in a table like this: http://ideone.com/iO4I8N

like image 802
Fox Avatar asked Oct 28 '13 11:10

Fox


2 Answers

You could iterate through all local variables via debug.getlocal and filter variables you're interested in by name. http://www.lua.org/pil/23.1.1.html

Here is example on how to use it.

local var1Age = 10
local var2Age = 20
local var3Age = 30

function local_var_value(n)
    local a = 1
    while true do
        local name, value = debug.getlocal(2, a)
        if not name then break end
        if name == n then
            return value
        end
        a = a + 1
    end
end

for i=1, 3 do
    local v = local_var_value("var"..i.."Age")
    if v and v >= 21 then
        print("yep")
    end
end
like image 179
keltar Avatar answered Sep 28 '22 07:09

keltar


Are you really sure you want to stretch the language usage this far? The use of debug library should be left for advanced use when you cannot do otherwise.

Maybe your programming problem could be solved in a more elegant way using "regular" Lua facilities. To have a sequence of variables indexed by a number, simply use a table as an array:

local varAge = {}
varAge[1] = 10
varAge[2] = 20
varAge[3] = 30

for i=1,#varAge do
    if varAge[i] >= 21 then
        print("yep")
    end
end

EDIT

If you really need to use debug.getlocal and performance is really an issue, you can avoid the potential O(n2) behavior scanning the locals only once and storing their values in a table:

local var1Age = 10
local var2Age = 20
local var3Age = 30

local function GetLocalVars( level )
    local result = {}
    for i = 1, math.huge do
        local name, value = debug.getlocal( level, i )
        if not name then break end
        result[ name ] = value
    end
    return result
end

local local_vars = GetLocalVars( 2 )

for i = 1, 3 do
    local name = "var"..i.."Age"
    local v = local_vars[ name ]
    if v and v >= 21 then
        print("yep")
    end
end
like image 38
Lorenzo Donati -- Codidact.com Avatar answered Sep 28 '22 07:09

Lorenzo Donati -- Codidact.com