Sorting Can';带关联索引的t排序表

Sorting Can';带关联索引的t排序表,sorting,indexing,lua,associative-array,lua-table,Sorting,Indexing,Lua,Associative Array,Lua Table,为什么不能使用table.sort对具有关联索引的表进行排序?,因为它们一开始没有任何顺序。这就像试图把装满香蕉的垃圾袋分类一样。因为它们一开始就没有任何顺序。这就像试图对装满香蕉的垃圾袋进行分类一样。一般来说,Lua表是纯关联数组。除了作为Lua核心中使用的特定哈希表实现的副作用之外,没有“自然”顺序。这是有意义的,因为任何Lua数据类型的值(除了nil)都可以用作键和值;但只有字符串和数字有任何合理的排序,并且只有在类似类型的值之间 例如,此表的排序顺序应为: unsortable = {

为什么不能使用table.sort对具有关联索引的表进行排序?

,因为它们一开始没有任何顺序。这就像试图把装满香蕉的垃圾袋分类一样。

因为它们一开始就没有任何顺序。这就像试图对装满香蕉的垃圾袋进行分类一样。

一般来说,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
通常,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开始的连续整数键的表进行排序,即列表。如果您有另一个键值对表,则可以创建一个键值对列表