2013-12-09 29 views
3

我正在尝试制作一个WoW插件,并将一些公会数据保存在二维数组中。我已经成功将数据保存到数组中,但无法将其恢复。如何在lua中循环遍历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循环。请注意,我的数组可能会跳过数字。我有Google,但大部分问题都知道他们的阵列有多长,我不知道。谢谢您的帮助!

+0

从下面的2个答案的带走的是,你不应该把你的guildMembers'的'列表作为二维数组因为这有点愚蠢的工作。相反,从“guildMembers”的一维列表的角度来看它。每个成员(列表上的项目)是存储您所需信息的表或对象。 – greatwolf

回答

1

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

-- 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 
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 
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