将带有字符串键的表值插入Lua表中

4
我是相对新手 Lua 语言,显然在表结构方面有些东西我没掌握。
我试图创建一个表格的表格,其中每个表格都有一个键,并且该值为相应的表格。
好的,这个陈述可能会令人困惑。下面是一个示例:
{{ key = "RC", value = {1, 2, 3, 4}},
 { key = "M",  value = {4, 8, 7}},
 { key = "D",  value = {3, 8, 9}}
 ...}

为此,我使用了以下算法:

local listOfLists = {};
...
if condition1 then
   listOfLists[key1] = list1;
end
...
if condition2 then
   listOfLists[key2] = list2;
end
...

等等...

我希望使用键后来确定哪些列表已添加到表中。 但问题是,即使所有条件都满足,似乎没有列表被添加到表中。

我可以使用table.insert(listOfLists, list1)代替listOfLists[key1] = list1,但那样我就无法知道哪些列表已添加到集合中。 有什么建议吗?


请注意,您提供的示例满足listOfLists[key1] = list1,其中key1是整数,list1的形式为{key="R", value={1,2,3,..}}。根据您的要求,更实用的结构可能是{ RC = {1,2,3,...}, M = {4,8,7}, ... },即key1是原始list1的键,而list1是值表。当条件1满足时,您能打印出key1list1吗?请执行print("key", type(key1), key1, "list", type(list1), list1) - Oliver
我明确地提到了“key”和“value”,以提供清晰度,但似乎反而增加了混淆。我尝试构建的正是您在评论中描述的 { RC = {1,2,3,...},M = {4,8,7},... },但并没有成功。 - memory of a dream
好的,那么我怀疑你获得的答案不会帮助解决“即使满足所有条件,也没有任何列表添加到表中”的问题。目前的状态如何?如果不是这样,我认为您需要发布更详细的代码,显示您拥有的结构、实际条件和添加项目到列表,因为您展示的看起来很好,所以问题在于未显示的代码中。 - Oliver
2个回答

3
Lua表格是一种灵活的数据结构,元素是键值对。键可以是除nil之外的任何Lua值。值可以是除nil之外的任何值。将nil分配给值会删除该键值对。
具有键值为从1到n的整数的number类型的子集(可能为空)称为序列。 n是与nil值配对的最后一个这样的键。几个表函数和运算符仅适用于序列。
表构造函数允许多种语法用于键:
  1. 通过序列隐含: {1, 2, 3}
  2. 显式键: {[1] = 1, [3] = 3, ["two"] = "value"}
  3. 标识符键: {one = 1, two = 2}
表构造函数可以使用它们的任意组合。
您定义了一个元素序列,每个元素都是具有两个元素的表,第二个元素是序列。
看起来您希望键为字符串,值为序列:
{ 
  RC = {1, 2, 3, 4},
  M = {4, 8, 7},
  D = {3, 8, 9}
}

谢谢Tom,你比我解释得更清楚。 这正是我想要的,但不幸的是我无法实现。 根据我在Lua.org上阅读的内容,我期望local listOfLists = {};listOfLists["RC"] = {1, 2, 3, 4};会生成类似{ RC = {1, 2, 3, 4}}的东西,但是在操作后listOfLists表仍然是{}。table.maxn(listOfLists)返回0。 - memory of a dream
1
在这种情况下,maxn 应该返回0,因为您没有任何类型为正整数的 number 键。唯一的键是字符串“RC”。尝试 table.maxn(listOfLists.RC);它应该是4。 - Tom Blodget

2
“很难理解,你想要实现什么。因此,如果您想要更具体的答案,请提供更多信息。”
“您可以创建表的关联表。”
local map = {}
map["key"] = { 1, 2, 3, 4 }
print(map.key[3])

或者你可以创建一个表的数组。
local vector = {}
vector[1] = { 1, 2, 3, 4 }
print(vector[1][2])

"或者您可以结合多种方法。创建…"
{{ key = "RC", value = {1, 2, 3, 4}},
{ key = "M",  value = {4, 8, 7}},
{ key = "D",  value = {3, 8, 9}}
...}

你可以使用表构造函数或者代码中的其他方法。
local tbl = { { key = "RC", value = {1, 2, 3, 4}} } -- init first elem from constructor
table.insert(tbl, { key = "M", value = {4, 8, 7}}) -- table insert & constructor
tbl[2] = {} -- Array-based access.
tbl[2].key = "D" --key access
tbl[2]["value"] = { 3, 8, 9 } -- other way

请注意,每个表格由两部分组成:顺序键从1到N的向量和其他部分的映射。一些函数,例如表长操作符或ipairs迭代器,仅保证与表的向量部分一起使用。但它们速度明显更快。
编辑:(最后一段说明)
如果您有一个带有某些键的表格并想要进行迭代,则可以使用ipairs或pairs。
ipairs是有序的,并且从1到第一个非nil元素。它不会迭代非整数键。 pairs 遍历任何键,但不保证顺序。
local map = { 1, 2, 3, key = 6, [5] = 5 }
for i, v in ipairs(map) do
  print(v) -- will output 1, 2, 3. first nil element is map[4]. map[5] will mot be visited.
end

for i, v in pairs(map) do -- NOTE pairs usage
  print(v) -- will output 1, 2, 3, 5, 6 in ANY order
end

map[4] = 4 -- Fill gap
for i, v in ipairs(map) do
   print(v) -- will output 1, 2, 3, 4, 5. Now first nil element is map[6]
end

长度运算符类似于 ipairs,它不计算未被 ipairs 方法访问的元素。 table.maxn 适用于数字索引,并且对于您的表将返回零。参考资料中说:
返回给定表的最大正数数字索引,如果表没有正数数字索引,则返回零。(为了完成其工作,此函数对整个表进行线性遍历。)
下面是关于长度和 table.maxn 的一个小例子。
local a = { 1, 2, 3, [5] = 5}
print(table.maxn(a)) -- 5
print(#a) -- 3
a = { key = 4 } 
print(table.maxn(a)) -- 0
print(#a) -- 0
print(a["key"]) -- 4, nothing is lost
local num = 0
for _, __ in pairs(a) do num = num + 1 end
print(num) -- 1 We find it.

1
还有可能的解决方案是{ RC = {1, 2, 3, 4}, ... } - hjpotter92
这与您的第一个示例类似,但是在执行map["key"] = { 1, 2, 3, 4 }之后,print(table.maxn(map));返回0,并且for key, value in ipairs(maxn) do ... end也不会进入循环。我不确定我做错了什么。顺便说一下,键可以是任何字符串,并且当我将数字列表(基本上是标识符列表)添加到“map”时,它永远不为空。 - memory of a dream
@memoryofadream ipairs 只遍历数字索引的元素,从 1 开始直到第一个非 nil 元素。我会在 5 分钟内在回答中添加更多解释。 - Seagull
@memoryofadream 扩展了答案。请查看编辑部分,特别是最后的代码示例。希望现在更清晰了。 - Seagull
@Seagull 感谢您提供详细信息。我会在大约4-5小时后告诉您结果。 - memory of a dream
@Seagull,你的解决方案很有效,谢谢。我看待数据的方式有误,而不是构建数据的方式。 - memory of a dream

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