Arrays 如何在lua中循环二维数组

Arrays 如何在lua中循环二维数组,arrays,for-loop,lua,add-on,world-of-warcraft,Arrays,For Loop,Lua,Add On,World Of Warcraft,我正在尝试制作一个魔兽世界插件,并在2D数组中保存一些公会数据。我已成功将数据保存到阵列中,但无法将其恢复 local playerName = UnitName("player"); ChatFrame1:AddMessage('Hi my name is: ' .. playerName); local guildMembers = {} local totalMembers, onlineMembers = GetNumGuildMembers(); local visibleMemb

我正在尝试制作一个魔兽世界插件,并在2D数组中保存一些公会数据。我已成功将数据保存到阵列中,但无法将其恢复

local playerName = UnitName("player");
ChatFrame1:AddMessage('Hi my name is: ' .. playerName);

local guildMembers = {}

local totalMembers, onlineMembers = GetNumGuildMembers();
local visibleMembers = onlineMembers;
local guildMembers = {}

if ( GetGuildRosterShowOffline() ) then
   visibleMembers = totalMembers;
end

for index=1, visibleMembers do
   local name = GetGuildRosterInfo(index);
   local weeklyXP = GetGuildRosterContribution(index);
   guildMembers[index] = {}
   guildMembers[index][1] = name;
   guildMembers[index][2] = weeklyXP;
   --DEFAULT_CHAT_FRAME:AddMessage('name: '..guildMembers[index][1]..' weeklyXP: '..guildMembers[index][2]);
end

for i, v in pairs(guildMembers) do
   for j, v2 in pairs(i) do
      print(i.. ': ' ..v.. ' xp: ' ..v2);
   end
end

除了最后一个嵌套for循环之外,一切似乎都正常。请注意,我的数组可能会跳过数字。我用谷歌搜索过,但大多数问题都知道他们的数组有多长,而我不知道。谢谢你的帮助

尝试使用数字for循环而不是通用for循环。

-#运算符获取表的长度
对于i=1,#行会成员,1 do
打印(i…“-名称:“…联合会成员[i][1]”;XP:“…联合会成员[i][2]);
结束
或者你可以使用字典:

localguildmembers={
name1=每周yxp1;
name2=weeklyXP2;
};
对于名称,xp成对(行会成员)执行
打印(名称:“.xp”);
结束
您应该在内部循环中使用
对(v)
,而不是
对(i)
,我认为您需要
.j..
而不是
.v..

   for j, v2 in pairs(v) do
      print(i.. ': ' ..j.. ' xp: ' ..v2);
   end
但是你应该用一张地图来表示内部,如

guildMembers[index] = {name=name, xp=weeklyXP}
然后,内部循环变为

   for j, v2 in pairs(v) do
      print(i.. ': ' ..j.. ' = ' ..v2);
   end

要在二维数组中循环,可以使用内部和外部的
ipairs()
迭代器,或者在常规的
for do
循环中按顺序使用数值索引的“索引”。您还可以对所有索引类型(如数字和字符串)使用
pairs()
,但将按“未定义”顺序使用

这两种方法都可以很好地使用,只是在代码的更深处,您有一个
ipairs
的问题,基本上假设您希望它“有序”,以及代码中的其他挫折迹象:)。这种混淆是很常见的。您还试图错误地迭代内部数组,您可以直接通过索引访问它们。你可以在ipairs(v)do中为j,v2做
,这是一个非常适合这种事情的习惯用法

在Lua中,表“包含”类似数组的索引数据、名称/值对数据,它们在内部是分开的,有时具有不同的语义。对于“成对”迭代器,它们是不同的。:)
ipairs()
对“索引”数据进行操作,
pairs()
迭代名称/值数据。当您使用
bob[i]=fred添加行时由于管理此操作的各种规则,您正在添加到表的“索引”部分

如果只需要内部元素,请将外部(和内部)视为任何表格:

for i, v in ipairs(guildMembers) do print(v[1] .. ':' ..v[2]) end
for i,v in ipairs(x) do for j,v2 in ipairs(v) do print(v2) end end
local guildMembers = {}
local visibleMembers = 10;

if visibleMembers then

    -- building using 'for'
    for index = 1, visibleMembers do
        local name = "name" .. index --GetGuildRosterInfo(index);
        local weeklyXP = index * 12345 --GetGuildRosterContribution(index);
        guildMembers[index] = {}
        guildMembers[index][1] = name;
        guildMembers[index][2] = weeklyXP;
    end

    -- reading using 'ipairs'
    for i, v in ipairs(guildMembers) do
        print(i.. ': ' ..v[1].. ' xp: ' ..v[2]);
    end
    -- or
    for i, v in ipairs(guildMembers) do
        for j, v2 in ipairs(v)    -- takes the 'object' in 'v' and iterates sub
            print(i..' '..j.. ': ' ..v2.. 'name or xp');
        end
    end

end
-- say my name
local playerName = UnitName("player");
ChatFrame1:AddMessage('Hi my name is: ' .. playerName);

-- locals
local guildMembers = {}

local totalMembers, onlineMembers = GetNumGuildMembers();
local visibleMembers = onlineMembers;

if thenGetGuildRosterShowOffline() then
    visibleMembers = totalMembers;
end

if visibleMembers then  
    -- build list
    for index=1, visibleMembers do
        local name = GetGuildRosterInfo(index);
        local weeklyXP = GetGuildRosterContribution(index);

        -- method 1   (ordered in likeliness of least to most expensive)
        --guildMembers[index] = { name, weeklyXP, }

        -- method 2
        --tinsert(guildMembers, { name, weeklyXP, })

        -- method 3
        --local item = { }; item[1] = name; item[2] = weeklyXP;
        --guildMembers[index] = item

        -- method 4 - original
        guildMembers[index] = {}
        guildMembers[index][1] = name;
        guildMembers[index][2] = weeklyXP;

        --DEFAULT_CHAT_FRAME:AddMessage('name: '..guildMembers[index][1]..
        --    ' weeklyXP: '..guildMembers[index][2]);
    end
    -- print
    for i, v in ipairs(guildMembers) do
        --for j, v2 in ipairs(i) do -- dont want loop if print in same line                     print(i.. ': ' ..v[1].. ' xp: ' ..v[2]);
        --end
    end
end
否则取一个内部元件,冲洗并重复:

for i, v in ipairs(guildMembers) do print(v[1] .. ':' ..v[2]) end
for i,v in ipairs(x) do for j,v2 in ipairs(v) do print(v2) end end
local guildMembers = {}
local visibleMembers = 10;

if visibleMembers then

    -- building using 'for'
    for index = 1, visibleMembers do
        local name = "name" .. index --GetGuildRosterInfo(index);
        local weeklyXP = index * 12345 --GetGuildRosterContribution(index);
        guildMembers[index] = {}
        guildMembers[index][1] = name;
        guildMembers[index][2] = weeklyXP;
    end

    -- reading using 'ipairs'
    for i, v in ipairs(guildMembers) do
        print(i.. ': ' ..v[1].. ' xp: ' ..v[2]);
    end
    -- or
    for i, v in ipairs(guildMembers) do
        for j, v2 in ipairs(v)    -- takes the 'object' in 'v' and iterates sub
            print(i..' '..j.. ': ' ..v2.. 'name or xp');
        end
    end

end
-- say my name
local playerName = UnitName("player");
ChatFrame1:AddMessage('Hi my name is: ' .. playerName);

-- locals
local guildMembers = {}

local totalMembers, onlineMembers = GetNumGuildMembers();
local visibleMembers = onlineMembers;

if thenGetGuildRosterShowOffline() then
    visibleMembers = totalMembers;
end

if visibleMembers then  
    -- build list
    for index=1, visibleMembers do
        local name = GetGuildRosterInfo(index);
        local weeklyXP = GetGuildRosterContribution(index);

        -- method 1   (ordered in likeliness of least to most expensive)
        --guildMembers[index] = { name, weeklyXP, }

        -- method 2
        --tinsert(guildMembers, { name, weeklyXP, })

        -- method 3
        --local item = { }; item[1] = name; item[2] = weeklyXP;
        --guildMembers[index] = item

        -- method 4 - original
        guildMembers[index] = {}
        guildMembers[index][1] = name;
        guildMembers[index][2] = weeklyXP;

        --DEFAULT_CHAT_FRAME:AddMessage('name: '..guildMembers[index][1]..
        --    ' weeklyXP: '..guildMembers[index][2]);
    end
    -- print
    for i, v in ipairs(guildMembers) do
        --for j, v2 in ipairs(i) do -- dont want loop if print in same line                     print(i.. ': ' ..v[1].. ' xp: ' ..v[2]);
        --end
    end
end
这是一个可以自己测试的模型:

for i, v in ipairs(guildMembers) do print(v[1] .. ':' ..v[2]) end
for i,v in ipairs(x) do for j,v2 in ipairs(v) do print(v2) end end
local guildMembers = {}
local visibleMembers = 10;

if visibleMembers then

    -- building using 'for'
    for index = 1, visibleMembers do
        local name = "name" .. index --GetGuildRosterInfo(index);
        local weeklyXP = index * 12345 --GetGuildRosterContribution(index);
        guildMembers[index] = {}
        guildMembers[index][1] = name;
        guildMembers[index][2] = weeklyXP;
    end

    -- reading using 'ipairs'
    for i, v in ipairs(guildMembers) do
        print(i.. ': ' ..v[1].. ' xp: ' ..v[2]);
    end
    -- or
    for i, v in ipairs(guildMembers) do
        for j, v2 in ipairs(v)    -- takes the 'object' in 'v' and iterates sub
            print(i..' '..j.. ': ' ..v2.. 'name or xp');
        end
    end

end
-- say my name
local playerName = UnitName("player");
ChatFrame1:AddMessage('Hi my name is: ' .. playerName);

-- locals
local guildMembers = {}

local totalMembers, onlineMembers = GetNumGuildMembers();
local visibleMembers = onlineMembers;

if thenGetGuildRosterShowOffline() then
    visibleMembers = totalMembers;
end

if visibleMembers then  
    -- build list
    for index=1, visibleMembers do
        local name = GetGuildRosterInfo(index);
        local weeklyXP = GetGuildRosterContribution(index);

        -- method 1   (ordered in likeliness of least to most expensive)
        --guildMembers[index] = { name, weeklyXP, }

        -- method 2
        --tinsert(guildMembers, { name, weeklyXP, })

        -- method 3
        --local item = { }; item[1] = name; item[2] = weeklyXP;
        --guildMembers[index] = item

        -- method 4 - original
        guildMembers[index] = {}
        guildMembers[index][1] = name;
        guildMembers[index][2] = weeklyXP;

        --DEFAULT_CHAT_FRAME:AddMessage('name: '..guildMembers[index][1]..
        --    ' weeklyXP: '..guildMembers[index][2]);
    end
    -- print
    for i, v in ipairs(guildMembers) do
        --for j, v2 in ipairs(i) do -- dont want loop if print in same line                     print(i.. ': ' ..v[1].. ' xp: ' ..v[2]);
        --end
    end
end
这是您的代码重做,可能会按原样工作:

for i, v in ipairs(guildMembers) do print(v[1] .. ':' ..v[2]) end
for i,v in ipairs(x) do for j,v2 in ipairs(v) do print(v2) end end
local guildMembers = {}
local visibleMembers = 10;

if visibleMembers then

    -- building using 'for'
    for index = 1, visibleMembers do
        local name = "name" .. index --GetGuildRosterInfo(index);
        local weeklyXP = index * 12345 --GetGuildRosterContribution(index);
        guildMembers[index] = {}
        guildMembers[index][1] = name;
        guildMembers[index][2] = weeklyXP;
    end

    -- reading using 'ipairs'
    for i, v in ipairs(guildMembers) do
        print(i.. ': ' ..v[1].. ' xp: ' ..v[2]);
    end
    -- or
    for i, v in ipairs(guildMembers) do
        for j, v2 in ipairs(v)    -- takes the 'object' in 'v' and iterates sub
            print(i..' '..j.. ': ' ..v2.. 'name or xp');
        end
    end

end
-- say my name
local playerName = UnitName("player");
ChatFrame1:AddMessage('Hi my name is: ' .. playerName);

-- locals
local guildMembers = {}

local totalMembers, onlineMembers = GetNumGuildMembers();
local visibleMembers = onlineMembers;

if thenGetGuildRosterShowOffline() then
    visibleMembers = totalMembers;
end

if visibleMembers then  
    -- build list
    for index=1, visibleMembers do
        local name = GetGuildRosterInfo(index);
        local weeklyXP = GetGuildRosterContribution(index);

        -- method 1   (ordered in likeliness of least to most expensive)
        --guildMembers[index] = { name, weeklyXP, }

        -- method 2
        --tinsert(guildMembers, { name, weeklyXP, })

        -- method 3
        --local item = { }; item[1] = name; item[2] = weeklyXP;
        --guildMembers[index] = item

        -- method 4 - original
        guildMembers[index] = {}
        guildMembers[index][1] = name;
        guildMembers[index][2] = weeklyXP;

        --DEFAULT_CHAT_FRAME:AddMessage('name: '..guildMembers[index][1]..
        --    ' weeklyXP: '..guildMembers[index][2]);
    end
    -- print
    for i, v in ipairs(guildMembers) do
        --for j, v2 in ipairs(i) do -- dont want loop if print in same line                     print(i.. ': ' ..v[1].. ' xp: ' ..v[2]);
        --end
    end
end

下面两个答案的要点是,你不应该将你的
guildMembers
列表视为一个2D数组,因为使用它有点迟钝。相反,从1D的
guildMembers
列表的角度使用它。每个成员(列表中的项)都是一个表或对象,用于存储所需的信息。