如何对 Lua 表进行字母排序?

我已经看过很多关于如何做到这一点的帖子,问题是,我仍然无法做到。

所有的例子都有额外的数据。比如像这样的东西

lines = {
  luaH_set = 10,
  luaH_get = 24,
  luaH_present = 48,
}

或者像这样,

obj = {
   { N = 'Green1'      },
   { N = 'Green'       },
   { N = 'Sky blue99'  }
}

我可以用一些语言编写代码,但我对 Lua 很陌生,而且表格对我来说真的很令人困惑。我似乎无法弄清楚如何调整示例中的代码才能对简单表格进行排序。

这是我的表:

local players = {"barry", "susan", "john", "wendy", "kevin"}

我想根据字母顺序排序这些名称。我知道 Lua 表格不保留排序,这就是我感到困惑的地方。我最关心的是按字母顺序打印这些名称,但我觉得我需要学会正确地索引它们到一个新表中。

我看到的示例如下:

local function cmp(a, b)
   a = tostring(a.N)
   b = tostring(b.N)
   local patt = '^(.-)%s*(%d+)$'
   local _,_, col1, num1 = a:find(patt)
   local _,_, col2, num2 = b:find(patt)
   if (col1 and col2) and col1 == col2 then
      return tonumber(num1) < tonumber(num2)
   end
   return a < b
end

table.sort(obj, cmp)
for i,v in ipairs(obj) do
   print(i, v.N)
end

或者是这样的:

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

for name, line in pairsByKeys(lines) do
  print(name, line)
end

我对这个问题感到非常困惑,不知道如何对简单的一维表格做同样的事情。

有没有人可以帮我理解这个问题?我知道如果我能理解最基本的示例,我就能自己学习这些更难的示例。

原文链接 https://stackoverflow.com/questions/71084051

点赞
stackoverflow用户2858170
stackoverflow用户2858170
local players = {"barry", "susan", "john", "wendy", "kevin"}

-- 以升序排序,默认设置
table.sort(players)
print(table.concat(players, ", "))

-- 以降序排序
table.sort(players, function(a,b) return a > b end)
print(table.concat(players, ", "))

以下是原因:

您的表 players 是一个序列。

local players = {"barry", "susan", "john", "wendy", "kevin"}

相当于

local players = {
  [1] = "barry",
  [2] = "susan",
  [3] = "john",
  [4] = "wendy",
  [5] = "kevin",
}

如果您在表构造函数中没有提供键,则 Lua 会自动使用整数键。

这样的表可以通过其值进行排序。Lua 会根据比较函数的返回值,在尊重 index value pairs 的基础上简单地重新排列。默认情况下,比较函数是

function(a,b) return a < b end

如果您想要任何其他顺序,您需要提供一个函数,如果元素 ab 之前,则返回 true。

阅读此处 https://www.lua.org/manual/5.4/manual.html#pdf-table.sort

table.sort 将列表元素就地按给定顺序排序,从 list[1] 到 list[#list]

本例不是“列表”或序列:

lines = {
  luaH_set = 10,
  luaH_get = 24,
  luaH_present = 48,
}

这相当于

lines = {
  ["luaH_set"] = 10,
  ["luaH_get"] = 24,
  ["luaH_present"] = 48,
}

它只有字符串作为键。它没有顺序。您需要一个帮助程序序列,将某些顺序映射到该表的元素中。

第二个例子

obj = {
   { N = 'Green1'      },
   { N = 'Green'       },
   { N = 'Sky blue99'  }
}

这相当于

obj = {
  [1] = { N = 'Green1'      },
  [2] = { N = 'Green'       },
  [3] = { N = 'Sky blue99'  },
}

是一个列表。所以您可以将其排序。但是按表值排序没有太多意义。因此,您需要提供一个函数,以合理的方式对其进行排序。

阅读此处以了解在此方面的“序列”或“列表”是什么意思。这些名称也用于其他东西。不要被困扰。

https://www.lua.org/manual/5.4/manual.html#3.4.7

它基本上是一个表,其连续整数键从 1 开始。

了解这种差异是学习 Lua 中最重要的概念之一。长度运算符、ipairs 和表库的许多函数仅适用于序列。

2022-02-11 17:37:41
stackoverflow用户1871033
stackoverflow用户1871033

为了澄清“不保留顺序”带来的混乱:不保留顺序的是表中值的,特别是对于字符串键,即当您将表用作字典而不是数组时。如果您编写 myTable = {orange="hello", apple="world"},则定义键 orange 在键 apple 左侧的事实不会被存储。如果您使用 for k, v in pairs(myTable) do print(k, v) end 枚举键/值,则实际上会在 apple world 之前获得 orange hello,因为 "apple" < "orange"。

但是,如果使用数字键(这是如果未指定键,则默认使用的键),则不会出现此问题-例如 myTable = {"hello", "world", foo="bar"}myTable = {[1]="hello", [2]="world", foo="bar"} 相同,即它将分配 myTable[1] = "hello",myTable[2] = "world"myTable.foo = "bar"(与 myTable["foo"] 相同)。(在这里,即使您会以随机顺序获取数字键 - 虽然不会,这也无关紧要,因为您仍然可以通过递增循环进行循环。)

您可以使用 table.sort,如果没有给出排序函数,它将使用 < 排序值,因此对于数字,结果是升序数字,对于字符串,则按 ASCII 码排序:

local players = {"barry", "susan", "john", "wendy", "kevin"}
table.sort(players)
-- players is now {"barry", "john", "kevin", "susan", "wendy"}

然而,如果您有大小写混合的条目,它会崩溃,因为大写字母将在小写字母之前,这是因为具有较低的 ASCII 代码,当然,它还不能正常处理如umlauts之类的非 ASCII 字符(它们将排在后面)-这不是字典排序。

但是,您可以提供自己的排序函数,它接受 (a, b) 参数并且需要返回 true,如果 a 应该出现在 b 之前。下面是一个解决小写和大写问题的示例,通过在比较之前转换为大写字母:

table.sort(players, function (a, b)
  return string.upper(a) < string.upper(b)
end)
2022-02-11 17:40:56
stackoverflow用户1847592
stackoverflow用户1847592

这是我的表格:

local players = {"barry", "susan", "john", "wendy", "kevin"}

我想要按字母表顺序对这些名字排序。

你只需要使用 table.sort(players)

我理解 LUA 表格并不保留顺序。

在 Lua 表格中,字段的顺序(一种带有任意键的字典)不会被保留。

但是,你的 Lua 表格是一个数组,它是由其整数键 1、2、3...自我排序的。

2022-02-11 17:41:15