无法排序与关联索引表
-
21-09-2019 - |
题
为什么我不能与关联索引使用table.sort来排序表?
解决方案
可以仅排序用从1开始的连续的整数密钥,即,列表表。如果你有键值对的另一个表,你可以对与那种列表:
function sortpairs(t, lt)
local u = { }
for k, v in pairs(t) do table.insert(u, { key = k, value = v }) end
table.sort(u, lt)
return u
end
当然,这仅当提供自定义排序(lt
),其预计作为参数的键/值对是有用的。
此问题是在更大的长度在约排序一个相关的问题讨论Lua中的表的。
其他提示
在一般情况下,Lua中的表是纯关联数组。没有“天然”的顺序比其他如Lua内核使用的特定哈希表实现的副作用。这是有意义的,因为任何的Lua数据类型(比nil
其他)的值可以被用作键和值;但只有字符串和数字有什么样合理的排序,然后只像类型值之间。
例如,又该该表的排序顺序是:
unsortable = {
answer=42,
true="Beauty",
[function() return 17 end] = function() return 42 end,
[math.pi] = "pi",
[ {} ] = {},
12, 11, 10, 9, 8
}
它有一个字符串键,一个布尔键,一个功能键,一个非整体式键,一个表键,以及五个整数密钥。如若功能排序提前串的?你如何比较的字符串是多少?应该在哪里表排序?并且怎么样不碰巧出现在该表userdata
和thread
值?
按照惯例,通过以1开始的连续整数索引的值通常被用作列表。几个功能和普通的成语遵守这个约定,并table.sort
就是一个例子。该工作在列表功能通常会忽略保存在不在列表中的一部分,密钥的任何值。再次,table.sort
是一个例子:它仅排序被存储在密钥属于列表的一部分的那些元素
又如#
运算符。对于上述表,#unsortable
是5,因为unsortable[5] ~= nil
和unsortable[6] == nil
。请注意,存储在数字索引math.pi
值不即使PI计数是3和4之间,因为它不是一个整数。此外,没有任何其他非整数键被任一计数。这意味着,对于环路简单可以遍历整个列表:
for i in 1,#unsortable do
print(i,unsortable[i])
end
虽然经常被写为
for i,v in ipairs(unsortable) do
print(i,v)
end
在短,Lua中的表是值的无序集合,各由一个键索引;但对于从1开始顺序整数密钥特殊的约定。
修改:用于非整键与合适的部分排序的特殊情况下,存在一个变通涉及一个单独的索引表。由字符串值键控表的描述内容是针对本特技合适的例子。
首先,收集的钥匙,一个新的表,以列表的形式。也就是说,使通过连续整数索引的表开始在1键的值和那种。然后,使用该索引来遍历原始表所需的顺序。
例如,这里是foreachinorder()
,这在一个表中的所有值利用此技术来迭代,要求每个键/值对的函数,以由比较功能确定的顺序。
function foreachinorder(t, f, cmp)
-- first extract a list of the keys from t
local keys = {}
for k,_ in pairs(t) do
keys[#keys+1] = k
end
-- sort the keys according to the function cmp. If cmp
-- is omitted, table.sort() defaults to the < operator
table.sort(keys,cmp)
-- finally, loop over the keys in sorted order, and operate
-- on elements of t
for _,k in ipairs(keys) do
f(k,t[k])
end
end
例如,下面的表中给出:
t1 = {
a = 1,
b = 2,
c = 3,
}
然后foreachinorder(t1,print)
打印:
a 1 b 2 c 3
和foreachinorder(t1,print,function(a,b) return a>b end)
打印:
c 3 b 2 a 1
由于它们不具有在第一位置的任何命令。这就像试图理清一个垃圾袋满香蕉的。