I am attempting to make a WoW addon and am saving some guild data in a 2D array. I have successfully saved the data to the array but am having trouble getting it back out.
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
Everything seems to work but for the last nested for loop. Just a note, my array may skip numbers. I have Google it but most of the questions asked knew how long their array was and I do not. Thanks for the help!
Try using a numerical for loop instead of a generic one.
-- 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
Or you could use a dictionary:
local guildMembers = {
name1 = weeklyXP1;
name2 = weeklyXP2;
};
for name, xp in pairs(guildMembers) do
print(name..": "..xp);
end
You should use pairs(v)
in inner loop, not pairs(i)
, and I think you want ..j..
not ..v..
:
for j, v2 in pairs(v) do
print(i.. ': ' ..j.. ' xp: ' ..v2);
end
But you should use a map for the inner part, as in
guildMembers[index] = {name=name, xp=weeklyXP}
then inner loop becomes
for j, v2 in pairs(v) do
print(i.. ': ' ..j.. ' = ' ..v2);
end
To loop through a 2D array, you can an inner and outer ipairs()
iterator, or an 'index' in a regular for do
loop for numerical indexes in order. You can also use pairs()
with all index types like numbers and strings, but will be in an 'undefined' order.
You use both fine except that farther down in your code, you have a pairs
vs. ipairs
issue basically assuming you wanted it 'in order', along with other signs of frustration in the code :). This confusion is very common. You also tried to iterate over the inner array incorrectly, you can just access them directly be index. You can do for j,v2 in ipairs(v) do
which is pretty much an idiom for this kind of thing.
In Lua tables 'contain' both array like indexed data, and name/value pair data, and they are separate internally and have 'sometimes' different semantics. In the case of 'pairs' iterators, they are different. :) The ipairs()
operates on the 'indexed' data, and pairs()
iterates the name / value data. When you added rows using bob[i]=fred;
you were adding to the 'indexed' part of the table, due to the various rules that govern this.
If wanted just the inner elements, treat the outer (and inner) like any table:
for i, v in ipairs(guildMembers) do print(v[1] .. ':' ..v[2]) end
Otherwise get an inner element, and just rinse and repeat:
for i,v in ipairs(x) do for j,v2 in ipairs(v) do print(v2) end end
Here is a mockup that can be tested by itself:
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
Here is your code redone, which will probably work as is:
-- 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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.