【问题标题】:Sorting a Lua table by key按键排序 Lua 表
【发布时间】:2025-12-17 04:50:01
【问题描述】:

我查看了很多问题和 Google 搜索结果,但找不到解决方案。

我正在尝试使用 Lua 中的 table.sort 函数对表进行排序,但我不知道如何使用它。

我有一个表,其中的键是随机数值。我想按升序对它们进行排序。我也浏览了 Lua wiki 页面,但 table.sort 仅适用于表值。

t = { [223]="asd", [23]="fgh", [543]="hjk", [7]="qwe" }

我想要这样:

t = { [7]="qwe", [23]="fgh", [223]="asd", [543]="hjk" }

【问题讨论】:

  • 你真正想解决什么问题?
  • 你给的代码不是正确的Lua代码...
  • 是的,我写错了,很抱歉给您带来不便。
  • 不要混淆 表构造函数(它有一个带有可选键的有序值列表)——一个源代码概念——和一个实际表 ——运行时数据结构。表构造函数中的顺序只与隐式键的赋值有关。
  • 返回“您真正想解决什么问题?”您似乎想要存储或使用比代码中更多的信息/结构。请说明目标。可能是您想要一个迭代器。可能是您想要不同的表结构。 ….

标签: sorting lua key lua-table


【解决方案1】:

您无法使用pairs 设置从散列(即您的表)中检索元素的顺序。您需要从该表中获取键,将键排序为自己的表,然后使用这些排序的键从原始表中检索值:

local t = { [223]="asd", [23]="fgh", [543]="hjk", [7]="qwe" }
local tkeys = {}
-- populate the table that holds the keys
for k in pairs(t) do table.insert(tkeys, k) end
-- sort the keys
table.sort(tkeys)
-- use the keys to retrieve the values in the sorted order
for _, k in ipairs(tkeys) do print(k, t[k]) end

这将打印出来

7   qwe
23  fgh
223 asd
543 hjk

另一种选择是提供您自己的迭代器而不是 pairs 以按您需要的顺序迭代表,但键的排序可能很简单,可以满足您的需要。

【讨论】:

    【解决方案2】:

    @lhf 所说的是真的,您的 lua 表以实现认为可行的任何顺序保存其内容。但是,如果您想以排序方式打印(或迭代),这是可能的(因此您可以逐个元素地比较它)。为此,您可以通过以下方式进行操作

    for key, value in orderedPairs(mytable) do
      print(string.format("%s:%s", key, value))
    end
    

    不幸的是,orderedPairs 没有作为 lua 的一部分提供,不过你可以从 here 复制实现。

    【讨论】:

      【解决方案3】:

      Lua 表中没有顺序的概念:它们只是键值对的集合。

      下面两个表的内容完全相同,因为它们包含完全相同的对:

      t = { [223] = "asd" ,[23] = "fgh",[543]="hjk",[7]="qwe"}
      t = {[7]="qwe",[23] = "fgh",[223] = "asd" ,[543]="hjk"}
      

      【讨论】:

      • 你是对的,但是我们可以将键设置为升序吗,因为当我比较这两个表时,它会变得不同,因为当我比较第一个键值对时,它将是 t[223] 和[7].如果两个表都是升序的,那么我可以很容易地找到丢失的键。
      • 手册says:“未指定枚举索引的顺序,即使对于数字索引也是如此。”它甚至可能从程序的一次运行更改为另一次。
      • 这个答案如何?这只是“放弃”。
      【解决方案4】:

      Lua sort docs 提供了很好的解决方案

      local function pairsByKeys (t, f)
          local a = {}
          for n in pairs(t) do table.insert(a, n) end
          table.sort(a, f)
          local i = 0      -- iterator variable
          local iter = function ()   -- iterator function
              i = i + 1
              if a[i] == nil then return nil
              else return a[i], t[a[i]]
              end
          end
          return iter
      end
      

      然后你遍历排序的结构

      local t = { b=1, a=2, z=55, c=0, qa=53, x=8, d=7 }
      for key,value in pairsByKeys(t) do
          print("  " .. tostring(key) .. "=" .. tostring(value))        
      end
      

      【讨论】: