3

我正在尝试制作一个 WoW 插件并将一些公会数据保存在 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 循环外,一切似乎都有效。请注意,我的数组可能会跳过数字。我有谷歌它,但大多数被问到的问题都知道他们的数组有多长,而我不知道。谢谢您的帮助!

4

3 回答 3

2

尝试使用数字 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
于 2013-12-09T22:58:34.193 回答
0

你应该pairs(v)在内部循环中使用, not 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
于 2013-12-10T00:31:11.440 回答
0

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

pairs除了在代码中更远的地方,您都可以很好地使用这两种方法,ipairs基本上假设您希望它“按顺序”运行,以及代码中的其他挫败迹象:)。这种混淆很常见。您还尝试错误地迭代内部数组,您可以直接访问它们作为索引。你可以做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
于 2013-12-11T00:37:04.430 回答