简体   繁体   中英

Pairs in lua programming

I have two set of values defined:

local A1 = {100, 200, 300, 400}
local A2 = {500, 600, 700, 800}

I want to iterate a loop assigning values for another variable B1 and B2 as pairs from A1 and A2 as follows:

B1 = 100 and B2 = 500 (first iteration)
B1 =200 and B2 = 600 (second iteration)
B1 = 300 and B2 = 700 (third iteration)
B1=400 and B2 = 800 (fourth iteration)

I tried to use ipairs as follows:

for i, f1 in ipairs(A1) do
for j, f2 in ipairs(A2) do
B1 = f1
B2 = f2
end
end

but this gave me

B1 = 100 and B2 = 500 (first iteration)
B1 =100 and B2 = 600 (second iteration)
B1 = 100 and B2 = 700 (third iteration)
B1=100 and B2 = 800 (fourth iteration)
B1 = 200 and B2 = 500 (fifth iteration)
B1 =200 and B2 = 600 (sixth iteration)
B1 =200 and B2 = 700 (seventh iteration)
....
...
...
so on...

can anyone help me to code in the right way?

You can easily do this with a numerical loop:

for i = 1, 4 do
    local a, b = A1[i], B1[i]
    --- use them
end

How you go about determining the number of iterations you'll need is the tricky part. If the sizes are variant, but each table is the same length as the others you can instead use the length operator ( #A1 ).

Alternatively, you might want a function that returns the largest length of a given set of tables.

local function max_table_len (...)
    local tabs = { ... }
    local len = 0

    for i = 1, #tabs do
        local l = #tabs[i]

        if l > len then
            len = l
        end
    end

    return len
end

And maybe even a helper function to get each value.

local function get_from_tables (index, ...)
    local values = { ... }
    local len = #values

    for i = 1, len do
        values[i] = values[i][index]
    end

    return table.unpack(values, 1, len)
end

Ending up with something like:

for index = 1, max_table_len(A1, B1) do
    local a, b = get_from_tables(index, A1, B1)
end

You can build on the ipairs example from Programming in Lua . For instance this version iterates over 2 sequences in parallel:

-- iterator function
local function iter_ipairs2(tablePair, i)
  i = i + 1
  local v1 = tablePair[1][i]
  local v2 = tablePair[2][i]
  -- if you use 'and' here the iteration stops after finishing
  -- the shortest sequence. If you use 'or' the iteration
  -- will stop after it finishes the longest sequence.
  if v1 and v2 then
    return i, v1, v2
  end
end

-- this is the function you'll call from your other code:
local function ipairs2(t1, t2)
  return iter_ipairs2, {t1, t2}, 0
end

-- usage:
local A1 = {100, 200, 300, 400, 500}
local A2 = {500, 600, 700, 800}

for i, v1, v2 in ipairs2(A1, A2) do
    print(i, v1, v2)
end

The previous answers are more detailed and provide a more general and better answer.

This one is for someone very new to Lua. Not only does it show two loops, it reinforces that there is usually more than one way to get where you want to go.

local A1 = {100, 200, 300, 400}
local A2 = {500, 600, 700, 800}

print("simplest answer:")
-- doesn't use ipairs and assumes A1 and A2 are the same size
for i = 1, #A1 do                
    B1 = A1[i]
    B2 = A2[i]
    print(B1, B2, "(iteration #"..i..")")
end

print()

print("answer that uses ipairs:")
-- again, assumes A1 and A2 are the same size
for i, v in ipairs(A1) do
    B1 = A1[i]      -- i steps through A1 and A2
    B2 = A2[i]      -- this works because A1 and A2 are same size
    print(B1, B2, "(iteration #"..i..")")
end

Gives this output:

simplest answer:
100 500 (iteration #1)
200 600 (iteration #2)
300 700 (iteration #3)
400 800 (iteration #4)

answer that uses ipairs:
100 500 (iteration #1)
200 600 (iteration #2)
300 700 (iteration #3)
400 800 (iteration #4)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM