luafreak
luafreak

Reputation: 115

Print a table in pairs

I'm trying to use in pairs inside a function but it doesn't work, it just prints the first row (key). This is my code:

set = {1,2,3,4};
unset = {5,6,7,8};

    function listen(ftype)
        if (ftype == [[~]]) then
            for num,str in pairs(set) do
                return str;
            end
        end
        if (ftype == [[$]]) then
            for num,str in pairs(unset) do
                return str;
            end
        end
    end

    print(listen([[~]])..[[ =:= ]]..listen([[$]]));

If I do something like this..

for num,str in pairs(unset) do
    print(str);
end

It works like a charm. That’s exactly what I want but inside a function.

Upvotes: 1

Views: 230

Answers (2)

Mark Reed
Mark Reed

Reputation: 95242

A function can't return multiple times. Putting an unconditional return inside a loop is nonsensical - it will never get to the second iteration of the loop.

You are essentially trying to return multiple values from the function. Lua supports that; you could, for instance, just return 1,2,3,4. For an unknown number of return values, you can build them up in a table and call unpack on it, like so:

function listen(ftype)
    local result = {}
    local num, str
    if (ftype == [[~]]) then
        for num,str in pairs(set) do
            table.insert(result, str)
        end
    elseif (ftype == [[$]]) then
        for num,str in pairs(unset) do
            table.insert(result, str)
        end
    end
    return unpack(result)
end

But since your results are already in a couple tables, it would be silly to reconstruct them that way. You can just unpack the originals:

function listen(ftype)
    if (ftype == [[~]]) then
        return unpack(set)
    elseif (ftype == [[$]]) then
        return unpack(unset)
    end
end

Great. But when you put the function call into an expression like your print statement, it will only return the first value, which puts you back where you started.

So to print out your pairs, you can't avoid having to either:

1) do some iteration outside the function
or
2) do the actual printing inside the function

The cleanest solution is probably a custom iterator, as suggested by @YuHao.

Upvotes: 2

Yu Hao
Yu Hao

Reputation: 122363

You can build your own iterator:

function double_pair(t1, t2)
    local i = 0
    return function() i = i + 1
               return t1[i] and t1[i] .. " =:= " .. t2[i] 
           end
end

Then you can use it like this:

for str in double_pair(set, unset) do
    print(str)
end

Output:

1 =:= 5
2 =:= 6
3 =:= 7
4 =:= 8

Note that you don't need semicolons to end your statement, unless the statements are in one line and you want to make them clear. And [[ =:= ]] is usually used to build long multi-line strings, normally we choose to use double quote " =:= " or single quote ' =:= '.

Upvotes: 7

Related Questions