【问题标题】:How to iterate through table in Lua?如何遍历Lua中的表?
【发布时间】:2013-06-30 11:47:18
【问题描述】:

所以,我有一个类似以下内容的表格:

arr =
{
  apples = { 'a', "red", 5 },
  oranges = { 'o', "orange", 12 },
  pears = { 'p', "green", 7 }
}

似乎无法根据索引访问它们,而值本身就是表,所以我只是将嵌套表的第一个值作为它的索引,所以现在看起来像这样:

arr =
{
  apples = { 0, 'a', "red", 5 },
  oranges = { 1, 'o', "orange", 12 },
  pears = { 2, 'p', "green", 7 }
}

所以,现在每当我使用这些表中的一个时,我都知道索引是什么,但仍然无法使用索引到达表,所以我开始编写一个循环遍历它们的函数,并检查索引,直到找到正确的索引。然后我意识到......如果我不能通过它们的索引引用它们,我该如何循环它们?所以,现在我被困住了。我真的很希望能够在大多数情况下输入 arr.apples 与 arr[1],但当然有时两者都需要。

【问题讨论】:

  • 除非每个数组行之间有一个“,”,否则@greatwolf 的回答将失败。 arr = { apples = { 0, 'a', "red", 5 }, oranges = { 1, 'o', "orange", 12 }, pears = { 2, 'p', "green", 7 }, } 可以在以下位置看到一个工作示例:ideone.com/yWKHx7
  • @KjellHedström 我已经编辑了 OP 的问题并修复了一些小的语法错误。很好的收获。

标签: arrays loops lua key lua-table


【解决方案1】:

要遍历表中的所有键值对,您可以使用pairs

for k, v in pairs(arr) do
  print(k, v[1], v[2], v[3])
end

输出:

pears   2   p   green
apples  0   a   red
oranges 1   o   orange

编辑:请注意,Lua 不保证表的关联部分的任何迭代顺序。如果您想按特定顺序访问项目,请从 arr 检索密钥并对其进行排序。然后通过排序后的key访问arr

local ordered_keys = {}

for k in pairs(arr) do
    table.insert(ordered_keys, k)
end

table.sort(ordered_keys)
for i = 1, #ordered_keys do
    local k, v = ordered_keys[i], arr[ ordered_keys[i] ]
    print(k, v[1], v[2], v[3])
end

输出:

  apples  a   red     5
  oranges o   orange  12
  pears   p   green   7

【讨论】:

  • 刚刚注意到...为什么它以错误的顺序打印它们?如果它按顺序打印它们,我可以省略表中的索引变量,而只依靠它打印的顺序来查找索引,这会很好。
  • Lua 不保证表的关联部分的迭代顺序。
  • @Lemony 我添加了一个示例,说明如何以特定顺序遍历表。
  • @HenrikErlandsson - JSON 对象是无序的。请参阅spec
  • 当 Crockford 写道“一个对象是一组无序的名称/值对”时,他的意思是 JSON 字符串表示一个对象,其中包含不应依赖其顺序的对。然而 JSON 是一种文本交换格式,人们所说的“JSON 对象”实际上只是一个字符串,所以是的,它是有序的。我个人认为“JSON 对象”这个词被过度使用了。 Henrik 是正确的,有人想要按照 JSON 字符串中给出的顺序进行迭代的 idea 是有效的,但确实是“错误的”!
【解决方案2】:

如果您想通过多个键引用嵌套表,您可以将它们分配给单独的键。这些表没有重复,并且仍然引用相同的值。

arr = {}
apples = {'a', "red", 5 }
arr.apples = apples
arr[1] = apples

此代码块允许您遍历表中的所有键值对 (http://lua-users.org/wiki/TablesTutorial):

for k,v in pairs(t) do
 print(k,v)
end

【讨论】:

    【解决方案3】:

    对于那些想知道为什么 ipairs 不会一直打印表的所有值的人,这就是原因(我会对此发表评论,但我没有足够的好男孩点)。

    ipairs 功能仅适用于键为 1 的元素的表。如果存在键为 1 的元素,ipairs 将按顺序尝试尽可能远, 1 -> 2 -> 3 -> 4 等等,直到它找不到具有序列中下一个键的元素。元素的顺序无关紧要。

    不符合这些要求的表格将无法与 ipairs 一起使用,请改用 pairs

    例子:

    ipairsCompatable = {"AAA", "BBB", "CCC"}
    ipairsCompatable2 = {[1] = "DDD", [2] = "EEE", [3] = "FFF"}
    ipairsCompatable3 = {[3] = "work", [2] = "does", [1] = "this"}
    
    notIpairsCompatable = {[2] = "this", [3] = "does", [4] = "not"}
    notIpairsCompatable2 = {[2] = "this", [5] = "doesn't", [24] = "either"}
    

    ipairs 将尽可能地进行迭代,但不会迭代表中的任何其他元素。

    kindofIpairsCompatable = {[2] = 2, ["cool"] = "bro", [1] = 1, [3] = 3, [5] = 5 }
    

    打印这些表格时,这些是输出。我还包含了 pairs 输出以供比较。

    ipairs + ipairsCompatable
    1       AAA
    2       BBB
    3       CCC
    
    ipairs + ipairsCompatable2
    1       DDD
    2       EEE
    3       FFF
    
    ipairs + ipairsCompatable3
    1       this
    2       does
    3       work
    
    ipairs + notIpairsCompatable
    
    pairs + notIpairsCompatable
    2       this
    3       does
    4       not
    
    ipairs + notIpairsCompatable2
    
    pairs + notIpairsCompatable2
    2       this
    5       doesnt
    24      either
    
    ipairs + kindofIpairsCompatable
    1       1
    2       2
    3       3
    
    pairs + kindofIpairsCompatable
    1       1
    2       2
    3       3
    5       5
    cool    bro
    

    【讨论】:

      【解决方案4】:

      这里的所有答案都建议使用 ipairs,但请注意,它并非一直都有效。

      t = {[2] = 44, [4]=77, [6]=88}
      
      --This for loop prints the table
      for key,value in next,t,nil do 
        print(key,value) 
      end
      
      --This one does not print the table
      for key,value in ipairs(t) do 
        print(key,value) 
      end
      

      【讨论】:

      • 为什么不一直打印?
      • 我是 Lua 的初学者。我不知道。但是我在测试我的代码时遇到了这个问题。
      • @sgowd 为什么要在表 't' 之后添加 ',nil' - 这不是必需的。您还提到的问题(实际上不是问题)是 ipairs 返回一组基于整数的键。这意味着如果您的表具有基于字符串的键,则使用 ipairs 会将它们转换为整数键。文档非常清楚地描述了差异。
      • @SeniruPasan 感谢您提供关于不添加 ',nil' 的提示;我会试试看。在我给出的示例中,键是基于整数的键。 Baggef 的回答stackoverflow.com/a/60088452/1566608 更清楚地说明了为什么 ipairs 不能一直工作。
      【解决方案5】:

      大家好,我是 LUA 的新手,但这些答案只帮助了我一半。所以我自己写。

      for i in pairs(actions) do 
          if actions[i][3] ~= nill then
          --do something
          end
      end
      
      1. i - 是表中的值索引,类似于 c# 中的索引
      2. 操作 - 只是表的名称
      3. actions[i][3] 如果第三个值不是 nil,它将检查表中的所有索引

      【讨论】:

        猜你喜欢
        • 2021-08-25
        • 2011-09-02
        • 2021-10-30
        • 2018-11-21
        • 1970-01-01
        • 2016-06-03
        • 2019-02-26
        • 2010-11-29
        相关资源
        最近更新 更多