【问题标题】:How do I loop through a 2D array in lua如何在lua中循环遍历二维数组
【发布时间】:2013-12-27 05:51:25
【问题描述】:

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

【问题讨论】:

  • 从下面的 2 个答案中得出的结论是,您不应将 guildMembers 列表视为 2D 数组,因为使用它有点迟钝。相反,从guildMembers 的一维列表的角度使用它。每个成员(列表中的项目)都是存储您需要的信息的表或对象。

标签: arrays for-loop lua add-on world-of-warcraft


【解决方案1】:

尝试使用数字 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

【讨论】:

    【解决方案2】:

    你应该在内循环中使用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
    

    【讨论】:

      【解决方案3】:

      要遍历 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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-12-22
        • 1970-01-01
        • 2019-02-04
        • 1970-01-01
        • 1970-01-01
        • 2018-03-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多