在 Lua 中按值关联排序表
Posted
技术标签:
【中文标题】在 Lua 中按值关联排序表【英文标题】:Associatively sorting a table by value in Lua 【发布时间】:2011-01-03 13:12:20 【问题描述】:我有一个键 => 值表,我想在 Lua 中排序。键都是整数,但不是连续的(并且有意义)。 Lua 唯一的排序函数似乎是table.sort
,它将表视为简单数组,丢弃原始键及其与特定项目的关联。相反,我基本上希望能够使用php's asort()
函数。
我有什么:
items =
[1004] = "foo",
[1234] = "bar",
[3188] = "baz",
[7007] = "quux",
排序操作后我想要什么:
items =
[1234] = "bar",
[3188] = "baz",
[1004] = "foo",
[7007] = "quux",
有什么想法吗?
编辑:根据答案,我假设这只是我正在使用的特定嵌入式 Lua 解释器的一个奇怪的怪癖,但在我的所有测试中,pairs()
始终按照添加到表中的顺序返回表项。 (即上述两个声明的迭代方式不同)。
不幸的是,因为这不是正常行为,我似乎无法得到我需要的东西; Lua 没有内置(当然)必要的工具,而且嵌入式环境太有限,我无法解决它。
不过,谢谢大家的帮助!
【问题讨论】:
这两张表一模一样。 【参考方案1】:你好像误会了什么。您在这里拥有的是associative array。关联数组没有明确的顺序,例如它只是对它们进行排序的内部表示(通常是排序的)。
简而言之——在 Lua 中,您发布的两个数组相同。
您想要的是这样的表示:
items =
1004, "foo",
1234, "bar",
3188, "baz",
7007, "quux",
虽然您现在无法通过索引获取它们(它们的索引为 1、2、3、4,但您可以创建另一个索引数组),但您可以使用 table.sort
对它们进行排序。
排序函数将是:
function compare(a,b)
return a[1] < b[1]
end
table.sort(items, compare)
【讨论】:
根据我的测试,这对 Lua 来说似乎不是真的。使用pairs()
迭代表时,顺序是稳定的,并且与添加项目的顺序相对应。此外,我没有选择更改数据存储方式的选项;我将结果输入到第 3 方库中,该库以“pairs()
order”向用户显示项目。
pairs 以哈希顺序返回数据 - 它可能是稳定的 - 但它不是添加项目的顺序。来自 lua-users wiki “注意,当使用字典时,不能保证键存储在表中的顺序,因此不能保证使用 pair() 检索键的顺序。这个警告甚至适用于索引表的一部分,或者在根本不用作字典并且只有索引作为键的表中。”
顺便说一句,return a[0] < b[0]
也咬了我太多次。 Lua 索引是从 1 开始的。
@Stavros - 天哪,这太奇怪了,以至于有人花了这么长时间才注意到它!
既然要比较字符串,不应该是return a[2] < b[2]
吗?【参考方案2】:
正如 Komel 所说,您正在处理关联数组,它们没有保证顺序。
如果您希望基于关联值的键排序同时保留关联数组功能,您可以执行以下操作:
function getKeysSortedByValue(tbl, sortFunction)
local keys =
for key in pairs(tbl) do
table.insert(keys, key)
end
table.sort(keys, function(a, b)
return sortFunction(tbl[a], tbl[b])
end)
return keys
end
items =
[1004] = "foo",
[1234] = "bar",
[3188] = "baz",
[7007] = "quux",
local sortedKeys = getKeysSortedByValue(items, function(a, b) return a < b end)
sortedKeys 是 1234,3188,1004,7007,您可以像这样访问您的数据:
for _, key in ipairs(sortedKeys) do
print(key, items[key])
end
结果:
1234 bar
3188 baz
1004 foo
7007 quux
【讨论】:
你刚刚拯救了我的一天,几个小时以来一直在为桌子排序而苦苦挣扎。血腥的命令..【参考方案3】:嗯,错过了无法控制迭代的部分。那里
但在 lua 中通常总有办法。
http://lua-users.org/wiki/OrderedAssociativeTable
这是一个开始。现在您需要替换库使用的pairs()。这可能是pairs = my_pairs的简单。然后您可以使用上面链接中的解决方案
【讨论】:
【参考方案4】:PHP 数组不同于 Lua 表。
一个 PHP 数组可能有一个键值对的有序列表。
Lua 表始终包含 无序集 键值对。
当程序员选择使用整数 1, 2, 3, ... 作为键时,Lua 表充当数组。语言语法和标准库函数,如 table.sort
为具有连续整数键的表提供特殊支持。
所以,如果你想模拟一个 PHP 数组,你必须使用键值对列表来表示它,这实际上是一个表的表,但将其视为键列表会更有帮助-值对。将自定义的“小于”函数传递给table.sort
,一切就绪。
注意Lua 允许您在 same 表中将连续整数键与任何其他类型的键混合 — 并且表示是有效的。我有时会使用这个功能,通常是用一些元数据标记一个数组。
【讨论】:
【参考方案5】:几个月后,使用相同的查询。推荐的答案似乎指出了所需的内容与在 LUA 中的外观之间的差距,但它并没有让我得到我真正想要的东西:- 这是一个按 Key 排序的哈希。
然而,此页面上的前三个函数 DID:http://lua-users.org/wiki/SortedIteration
【讨论】:
但这恰恰是相反的问题:这个问题是按值排序。您的答案是按键排序。【参考方案6】:几年前我做了一点 Lua 编码,但我不再流利了。
当遇到类似问题时,我将我的数组复制到另一个数组,键和值颠倒,然后在新数组上使用sort
。
我不知道可以使用 Kornel Kisielewicz 推荐的方法对数组进行排序。
【讨论】:
以上是关于在 Lua 中按值关联排序表的主要内容,如果未能解决你的问题,请参考以下文章