Sorting Can';带关联索引的t排序表
为什么不能使用table.sort对具有关联索引的表进行排序?,因为它们一开始没有任何顺序。这就像试图把装满香蕉的垃圾袋分类一样。因为它们一开始就没有任何顺序。这就像试图对装满香蕉的垃圾袋进行分类一样。一般来说,Lua表是纯关联数组。除了作为Lua核心中使用的特定哈希表实现的副作用之外,没有“自然”顺序。这是有意义的,因为任何Lua数据类型的值(除了Sorting Can';带关联索引的t排序表,sorting,indexing,lua,associative-array,lua-table,Sorting,Indexing,Lua,Associative Array,Lua Table,为什么不能使用table.sort对具有关联索引的表进行排序?,因为它们一开始没有任何顺序。这就像试图把装满香蕉的垃圾袋分类一样。因为它们一开始就没有任何顺序。这就像试图对装满香蕉的垃圾袋进行分类一样。一般来说,Lua表是纯关联数组。除了作为Lua核心中使用的特定哈希表实现的副作用之外,没有“自然”顺序。这是有意义的,因为任何Lua数据类型的值(除了nil)都可以用作键和值;但只有字符串和数字有任何合理的排序,并且只有在类似类型的值之间 例如,此表的排序顺序应为: unsortable = {
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循环可以遍历整个列表:
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
然后foreachinorder(t1,打印)
打印:
a 1
b 2
c 3
c 3
b 2
a 1
通常,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循环可以遍历整个列表:
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
然后foreachinorder(t1,打印)
打印:
a 1
b 2
c 3
c 3
b 2
a 1
只能对具有从1开始的连续整数键的表进行排序,即列表。如果您有另一个键值对表,则可以创建一个键值对列表