2013-12-09 56 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