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