如何在lua中循环遍历2D数组

时间:2013-12-09 22:27:06

标签: 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 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循环。请注意,我的数组可能会跳过数字。我有谷歌它,但大多数问题知道他们的阵列有多长,我没有。谢谢你的帮助!

3 个答案:

答案 0 :(得分:1)

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

-- The # operator gets the length of a table
for i = 1, #guildMembers, 1 do
    print(i.." - Name: "..guildMembers[i][1].."; XP: "..guildMembers[i][2]);
end

或者你可以使用字典:

local guildMembers = {
    name1 = weeklyXP1;
    name2 = weeklyXP2;
};
for name, xp in pairs(guildMembers) do
    print(name..": "..xp);
end

答案 1 :(得分:0)

您应该在内部循环中使用pairs(v),而不是pairs(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

答案 2 :(得分:0)

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

你使用两者都很好,除了你的代码中更远的地方,你有一个pairsipairs问题,基本上假设你想要'按顺序',以及代码中其他令人沮丧的迹象:)。这种混乱很常见。您还试图错误地迭代内部数组,您可以直接访问它们是索引。你可以做for j,v2 in ipairs(v) do这对于这种事情来说就是一个习惯用语。

在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