为什么我不能与关联索引使用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
}

它有一个字符串键,一个布尔键,一个功能键,一个非整体式键,一个表键,以及五个整数密钥。如若功能排序提前串的?你如何比较的字符串是多少?应该在哪里表排序?并且怎么样不碰巧出现在该表userdatathread值?

按照惯例,通过以1开始的连续整数索引的值通常被用作列表。几个功能和普通的成语遵守这个约定,并table.sort就是一个例子。该工作在列表功能通常会忽略保存在不在列表中的一部分,密钥的任何值。再次,table.sort是一个例子:它仅排序被存储在密钥属于列表的一部分的那些元素

又如#运算符。对于上述表,#unsortable是5,因为unsortable[5] ~= nilunsortable[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

它构造的指标,与 table.sort() ,然后在排序索引的每个元素遍历并调用为每个功能f。该功能f传递键和值。排序顺序由被传递给table.sort可选比较函数来确定。这就是所谓的两个元素进行比较(在这种情况下,密钥表t)和必须返回true如果第一个小于第二个。如果省略,table.sort使用内置在<运算符。

例如,下面的表中给出:

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

由于它们不具有在第一位置的任何命令。这就像试图理清一个垃圾袋满香蕉的。

scroll top