你可以在Lua表中使用数字键吗?

11
以下示例旨在创建一个表格,可以在数字和字符串之间进行转换,但无法运行。
是因为我使用了数字键以字典类型的方式吗? 还是因为lua从1开始对表格索引?
有更好的方法来实现这个吗?
dyeColor = {
    0="black"    ,  black     = 0,
    1="red"      ,  red       = 1, 
    2="green"    ,  green     = 2,
    3="brown"    ,  brown     = 3,
    4="blue"     ,  blue      = 4,
    5="purple"   ,  purple    = 5,
    6="cyan"     ,  cyan      = 6,
    7="lightGray",  lightGray = 7,
    8="gray"     ,  gray      = 8,
    9="pink"     ,  pink      = 9,
    10="lime"     ,  lime      =10,
    11="yellow"   ,  yellow    =11,
    12="lightBlue",  lightBlue =12,
    13="magenta"  ,  magenta   =13,
    14="orange"   ,  orange    =14,
    15="white"    ,  white     =15}

使用这个在线解释器 (http://repl.it/languages/Lua) 出现了错误。 [string "stdin"]:2: 预计需要 '}' (在第1行关闭 '{') 附近的 '='尝试调用一个空值

它到底是如何“无法运行”的? - Keith Thompson
添加了我收到的错误消息。 - Ryan Leach
1
抵消问题的一个踩因为 OP 已经参与并展示了一些努力。我自己不能抵消另一个,但即使我能,也可能不会,因为答案确实相当于阅读和理解语言本身的基本语法。 - RBerteig
3个回答

23

您需要将数字索引放在方括号中:

dyeColor = {
    [0]="black"     ,  black     = 0,
    [1]="red"       ,  red       = 1, 
    [2]="green"     ,  green     = 2,
    [3]="brown"     ,  brown     = 3,
    [4]="blue"      ,  blue      = 4,
    [5]="purple"    ,  purple    = 5,
    [6]="cyan"      ,  cyan      = 6,
    [7]="lightGray" ,  lightGray = 7,
    [8]="gray"      ,  gray      = 8,
    [9]="pink"      ,  pink      = 9,
    [10]="lime"     ,  lime      =10,
    [11]="yellow"   ,  yellow    =11,
    [12]="lightBlue",  lightBlue =12,
    [13]="magenta"  ,  magenta   =13,
    [14]="orange"   ,  orange    =14,
    [15]="white"    ,  white     =15}

你可以使用以下方法来减少输入:

dyeColor = {
    [0]="black"     ,
    [1]="red"       ,
    [2]="green"     ,
    [3]="brown"     ,
    [4]="blue"      ,
    [5]="purple"    ,
    [6]="cyan"      ,
    [7]="lightGray" ,
    [8]="gray"      ,
    [9]="pink"      ,
    [10]="lime"     ,
    [11]="yellow"   ,
    [12]="lightBlue",
    [13]="magenta"  ,
    [14]="orange"   ,
    [15]="white"    }

for i = 0, #dyeColor do dyeColor[dyeColor[i]] = i end

Lua允许Name = exp形式的Name作为fieldspec,但不允许使用数字。数字必须用括号括起来。同样的规则适用于字段引用。你可以这样写:

dyeColor.black

但不是

dyeColor.0 -- you may say dyeColor[0] of course

如果你能够解释你的答案与问题中给出的代码有何不同(从解释器的角度),我将接受你的答案。 - Ryan Leach
甚至可以通过不定义除 [0] 之外的索引来节省更多的打字。 - hjpotter92
1
是的,在这种情况下,我将数字视为映射重要性的文档,即这不仅仅是一个数组,因此看到关联是很好的。当然,这是个人口味问题。 - Doug Currie

0

#dyeColor 如果包含 [0] 则未定义,所以您可以

dyeColor = {} do
  local tmp= {
    "black"     ,
    "red"       ,
    "green"     ,
    "brown"     ,
    "blue"      ,
    "purple"    ,
    "cyan"      ,
    "lightGray" ,
    "gray"      ,
    "pink"      ,
    "lime"      ,
    "yellow"    ,
    "lightBlue" ,
    "magenta"   ,
    "orange"    ,
    "white"    
  }
  for i, v in ipairs(tmp) do
    local j = i - 1
    dyeColor[v], dyeColor[j] = j, v
  end
end

表中带有项[0]的长度是否未定义?我对5.1和5.2的定义都有所阅读,得出结论它是被定义的,例如5.2:其正数数字键的集合等于某个整数n的{1..n}。我猜这取决于您是否在此上下文中将0视为正数。在5.1中,它肯定是被定义的:任何整数索引n,使得t[n]不为nil且t[n+1]为nil--即使使用[0]时也只有一个这样的值。 - Doug Currie
我猜测在这个解决方案中映射从1开始?如果是这样,那么这个答案就没用了,因为0是需要表示我无法控制的数据。 - Ryan Leach
哦,真的吗?如果 #dyeColor 包含 [0],那么它就被定义了。 - moteus

0

改进Doug Curie的解决方案:

local dyeColor = {
    [0] = "black", -- You must set 0 explicitly
    "red"        , -- Unnamed items get their numeric index 
    "green"      , -- automatically, starting at 1.
    "brown"      ,
    "blue"       ,
    "purple"     ,
    "cyan"       ,
    "lightGray"  ,
    "gray"       ,
    "pink"       ,
    "lime"       ,
    "yellow"     ,
    "lightBlue"  ,
    "magenta"    ,
    "orange"     ,
    "white"
}
for i = 0, #dyeColor do dyeColor[dyeColor[i]] = i end

尽管在Lua 5.2中,带有[0]的表的长度未定义,但实际上它返回最后一个元素的索引。上面的代码也适用于Lua 5.1和LuaJIT。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接