2

我正在使用 Lua 中的关联数组/表。我想将不区分大小写的用户输入与表中区分大小写的键进行比较。

前任:

table = { ["HellO"] = "world" }
user_input = "hello"
table_entry = table[user_input]

如果可能的话,我希望上面的示例以存储在 table_entry 中的“world”结尾。

但是,我真的很想避免遍历整个表(这会很大)并将 string.lower(key) 与 string.lower(user_input) 进行比较。

此外,我无法控制表的创建,因此我无法仅使用小写/大写键创建它。

任何反馈表示赞赏,谢谢。

4

3 回答 3

3

也许创建另一个表,将键的小写版本映射到原始表中的(可能是 0、1 或更多)混合大小写键。然后小写用户输入并在新表中查找。

于 2012-08-08T15:12:21.397 回答
3

你没有说你打算对冲突做什么(原始表包含'hello''Hello',具有不同的值。

您不会说原始表是否会更新或是否已修复。如果要更新而您无法拦截更新,那您就完蛋了,因为您永远不知道真相会是什么。

一些想法:

  • 如果原始表永远不会被更新,那么您可以制作一个“影子”表,它使用原始表的键被粉碎为小写:

    shadow = { }
    for k, v in pairs(original) do shadow[k:lower()] = v end 
    

    使用shadow[userkey:lower()].

  • 如果要更新原始表,但大多数键都会命中,您可以构建一个大小写映射,将等效的混合大小写提供给任何小写:

    mixed = { }
    for k in pairs(original) do mixed[k:lower()] = k end
    

    查找使用original[mixed[userkey:lower()]](仅当mixed[...]不为零时)。

    在这种情况下,如果您获得了一个好的密钥,即使值已更改,您也会被设置。但是,如果您丢失了钥匙,您将不得不做一些昂贵的事情。(除非您可以拦截更新。)

如果原始表超出了您的控制范围,并且您无法检测到它何时更新,那么您就真的搞砸了。在这种情况下,我会尝试插入一个空表并使用__index__newindex元方法来记录更新。这会增加开销,但仍然比线性搜索便宜。

于 2012-08-08T21:42:47.130 回答
0

我无法控制表的创建,所以我不能只用小写/大写键创建它。

然后你必须至少遍历一次。这是一个哈希表;没有办法让不同的字符串散列到相同的值(不改变 Lua 的核心)。

如果内存不是问题,您可以进行一次遍历以创建新的查找表。如果内存是个问题,您每次都必须遍历整个表。

或者找到某种方法来控制该表的创建。:)

于 2012-08-08T18:08:32.723 回答