以 Lua 中的值为标准对表进行关联排序
我有一张键值对表,想在 Lua 中对其进行排序。键都是整数,但不连续(并且有意义)。Lua 的唯一排序函数似乎是table.sort
,它将表视为简单的数组,丢弃原始键及其与特定项目的关联。相反,我基本上想使用 PHP 的 asort()
函数。
我有什么:
items = {
[1004] = "foo",
[1234] = "bar",
[3188] = "baz",
[7007] = "quux",
}
排序操作后我想要的:
items = {
[1234] = "bar",
[3188] = "baz",
[1004] = "foo",
[7007] = "quux",
}
有什么想法吗?
编辑:根据答案,我将假定它只是我正在使用的特定嵌入式 Lua 解释器的奇怪瑕疵,但在我所有的测试中,pairs()
始终以它们添加到表中的顺序返回表项。(即上面的两个声明会遍历不同)。
不幸的是,因为这不是正常行为,看起来我无法得到我需要的;Lua 没有必要的内置工具(当然),并且嵌入式环境过于有限,无法绕过它。
不过,还是谢谢大家的帮助!
原文链接 https://stackoverflow.com/questions/2038418
我在几年前做过一点点 Lua 编程,但现在已经不太熟练了。
当遇到类似的问题时,我将数组复制到另一个数组中,然后将键和值颠倒,接着在新数组上使用 sort
方法。
我不知道可以使用 Kornel Kisielewicz 推荐的方法对数组进行排序。
尝试使用 Lua 中的有序关联表
哦,我没注意到不能控制迭代这一点。不过,在 Lua 中通常总有办法。
http://lua-users.org/wiki/OrderedAssociativeTable
这是一个开始。现在,你需要替换库使用的 pairs() 函数。这可能只需要把 pairs=my_pairs。然后,你可以使用上面链接中的解决方案。
PHP 数组与 Lua 表格不同。
PHP 数组可以有 有序 的键值对列表。
Lua 表格总是包含 无序 的键值对集合。
当程序员选择使用整数 1、2、3 等作为键时,Lua 表格就像一个数组一样。语言语法和标准库函数,例如 table.sort
,为具有连续整数键的表格提供了特殊支持。
因此,如果要模拟 PHP 数组,必须使用键值对列表来表示它,这实际上是一个表格的表格,但将其视为键值对列表更有帮助。向 table.sort
传递自定义的“小于”函数,然后就可以设置好了。
注意:Lua 允许您在 相同的 表格中 混合使用 连续整数键和其他任何类型的键——并且表示效率很高。我有时会使用此功能,通常将一些元数据与数组标记。
几个月后再来,有同样的疑问。建议的答案似乎指出了所需的东西与LUA中的实际情况之间的差距,但它并没有完全提供我需要的答案——即一个按键排序的哈希表。
不过,这个页面上的前三个函数确实提供了我需要的:http://lua-users.org/wiki/SortedIteration
正如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
所提议的compare
函数可以工作,但只有在第一列中的值是唯一的情况下才有效。
以下是增强版的 compare
函数,以确保如果实际列的值相等,则从下一列中取值进行评估......
如果{1234,"baam"} < {1234,"bar"}
为true
,则包含“baam”的数组将插入到包含“bar”的数组之前。
local items = {
{1004,"foo" },
{1234,"bar " },
{1234,"baam" },
{3188,"baz " },
{7007,"quux" },
}
local function compare(a,b)
for inx = 1,#a do
- -打印("A " .. inx .." ".. a [inx] )
- -打印("B " .. inx .." ".. b [inx] )
if a [inx] == b [inx] and a [inx + 1] <b [inx + 1] then
返回true
elseif a [inx] ~ = b [inx] and a [inx] <b [inx] == true then
返回true
其他
返回false
结束
end
返回false
end
table.sort(items,compare)
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法
- 如何编写 Lua 模式将字符串(嵌套数组)转换为真正的数组?
你似乎误解了一些东西。你现在有的是一个关联数组。关联数组之间没有明确的顺序,例如,只有内部表示(通常是排序的)才排序。
简而言之,在 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)