如何按 "score" 然后 "index" 对 Lua 中的内部表进行排序?
How to sort inner tables in Lua by their "score" and then "index"?
我将以下 Lua table 存储在变量 T
中:
{
["mn"] = { ["index"] = 7, ["key"] = "mn", ["score"] = 0 },
["kl"] = { ["index"] = 6, ["key"] = "kl", ["score"] = .4 },
["ef"] = { ["index"] = 3, ["key"] = "ef", ["score"] = .3 },
["ab"] = { ["index"] = 1, ["key"] = "ab", ["score"] = 0 },
["cd"] = { ["index"] = 2, ["key"] = "cd", ["score"] = .1 },
["gh"] = { ["index"] = 4, ["key"] = "gh", ["score"] = 0 },
["ij"] = { ["index"] = 5, ["key"] = "ij", ["score"] = .2 }
}
我想按以下方式对 T
table 的所有内部 table 进行排序:
1. score
高的表放在最前面
2. score
相等的表按 index
排序。
因此,排序后,输出应产生以下顺序 table:
{
[1] = { ["index"] = 6, ["key"] = "kl", ["score"] = .4 }, -- highest "score"
[2] = { ["index"] = 3, ["key"] = "ef", ["score"] = .3 },
[3] = { ["index"] = 5, ["key"] = "ij", ["score"] = .2 },
[4] = { ["index"] = 2, ["key"] = "cd", ["score"] = .1 },
[5] = { ["index"] = 1, ["key"] = "ab", ["score"] = 0 }, -- lowest "score", lowest "index"
[6] = { ["index"] = 4, ["key"] = "gh", ["score"] = 0 }, -- when scores are the same, sort by their "index" instead
[7] = { ["index"] = 7, ["key"] = "mn", ["score"] = 0 } -- lowest "score", highest "index"
}
如何实现这个Luatable排序?
在lua中,table包含两种数据结构:数组和字典。
排序是指对数组进行排序,其中每个元素都与一个数字索引相关联,并且索引是连续的,即:1,2,3...
你的初始 table 实际上是一个字典 - 每个条目都有一个与之关联的任意键(在你的情况下,它们是字符串)。
因此,您描述的实际上不是排序任务,您最终想要一种不同的table。
table.sort
适用于 lua table 的数组部分,即索引从 1 开始到第一个 nil 条目结束的那些元素。
a={s=3,['r']=3, 5,3,2, nil,21}
|these|
|ones |
因此,您首先创建一个数组并对其进行排序:
local sorted={}
for k,v in pairs(T) do
table.insert(sorted,v)
end
table.sort(sorted,function(a,b)
--your code here
--function should return true if element `a` from the array `sorted`
--must be higher (to the left of) `b`
end)
或者,您可以将条目存储在字典和数组部分的相同 table 中,table.sort
函数将忽略字典。但是使用 pairs
遍历 table 并同时添加新元素是不明智的。因此,惯用的方式仍然会涉及中间副本。
您需要先将您拥有的哈希值转换为 table,然后使用按 score
(降序)排序的自定义排序函数对 table 的元素进行排序) 然后 index
(升序)对于那些具有相同分数的元素。
像这样的东西应该可以工作:
local hash = {
["mn"] = { ["index"] = 7, ["key"] = "mn", ["score"] = 0 },
["kl"] = { ["index"] = 6, ["key"] = "kl", ["score"] = .4 },
["ef"] = { ["index"] = 3, ["key"] = "ef", ["score"] = .3 },
["ab"] = { ["index"] = 1, ["key"] = "ab", ["score"] = 0 },
["cd"] = { ["index"] = 2, ["key"] = "cd", ["score"] = .1 },
["gh"] = { ["index"] = 4, ["key"] = "gh", ["score"] = 0 },
["ij"] = { ["index"] = 5, ["key"] = "ij", ["score"] = .2 }
}
local tbl = {}
for _,v in pairs(hash) do
table.insert(tbl, v)
end
table.sort(tbl, function(a,b)
return a.score > b.score or a.score == b.score and a.index < b.index
end)
我将以下 Lua table 存储在变量 T
中:
{
["mn"] = { ["index"] = 7, ["key"] = "mn", ["score"] = 0 },
["kl"] = { ["index"] = 6, ["key"] = "kl", ["score"] = .4 },
["ef"] = { ["index"] = 3, ["key"] = "ef", ["score"] = .3 },
["ab"] = { ["index"] = 1, ["key"] = "ab", ["score"] = 0 },
["cd"] = { ["index"] = 2, ["key"] = "cd", ["score"] = .1 },
["gh"] = { ["index"] = 4, ["key"] = "gh", ["score"] = 0 },
["ij"] = { ["index"] = 5, ["key"] = "ij", ["score"] = .2 }
}
我想按以下方式对 T
table 的所有内部 table 进行排序:
1. score
高的表放在最前面
2. score
相等的表按 index
排序。
因此,排序后,输出应产生以下顺序 table:
{
[1] = { ["index"] = 6, ["key"] = "kl", ["score"] = .4 }, -- highest "score"
[2] = { ["index"] = 3, ["key"] = "ef", ["score"] = .3 },
[3] = { ["index"] = 5, ["key"] = "ij", ["score"] = .2 },
[4] = { ["index"] = 2, ["key"] = "cd", ["score"] = .1 },
[5] = { ["index"] = 1, ["key"] = "ab", ["score"] = 0 }, -- lowest "score", lowest "index"
[6] = { ["index"] = 4, ["key"] = "gh", ["score"] = 0 }, -- when scores are the same, sort by their "index" instead
[7] = { ["index"] = 7, ["key"] = "mn", ["score"] = 0 } -- lowest "score", highest "index"
}
如何实现这个Luatable排序?
在lua中,table包含两种数据结构:数组和字典。
排序是指对数组进行排序,其中每个元素都与一个数字索引相关联,并且索引是连续的,即:1,2,3...
你的初始 table 实际上是一个字典 - 每个条目都有一个与之关联的任意键(在你的情况下,它们是字符串)。
因此,您描述的实际上不是排序任务,您最终想要一种不同的table。
table.sort
适用于 lua table 的数组部分,即索引从 1 开始到第一个 nil 条目结束的那些元素。
a={s=3,['r']=3, 5,3,2, nil,21}
|these|
|ones |
因此,您首先创建一个数组并对其进行排序:
local sorted={}
for k,v in pairs(T) do
table.insert(sorted,v)
end
table.sort(sorted,function(a,b)
--your code here
--function should return true if element `a` from the array `sorted`
--must be higher (to the left of) `b`
end)
或者,您可以将条目存储在字典和数组部分的相同 table 中,table.sort
函数将忽略字典。但是使用 pairs
遍历 table 并同时添加新元素是不明智的。因此,惯用的方式仍然会涉及中间副本。
您需要先将您拥有的哈希值转换为 table,然后使用按 score
(降序)排序的自定义排序函数对 table 的元素进行排序) 然后 index
(升序)对于那些具有相同分数的元素。
像这样的东西应该可以工作:
local hash = {
["mn"] = { ["index"] = 7, ["key"] = "mn", ["score"] = 0 },
["kl"] = { ["index"] = 6, ["key"] = "kl", ["score"] = .4 },
["ef"] = { ["index"] = 3, ["key"] = "ef", ["score"] = .3 },
["ab"] = { ["index"] = 1, ["key"] = "ab", ["score"] = 0 },
["cd"] = { ["index"] = 2, ["key"] = "cd", ["score"] = .1 },
["gh"] = { ["index"] = 4, ["key"] = "gh", ["score"] = 0 },
["ij"] = { ["index"] = 5, ["key"] = "ij", ["score"] = .2 }
}
local tbl = {}
for _,v in pairs(hash) do
table.insert(tbl, v)
end
table.sort(tbl, function(a,b)
return a.score > b.score or a.score == b.score and a.index < b.index
end)