首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何按字母顺序对一个简单的Lua表进行排序?

如何按字母顺序对一个简单的Lua表进行排序?
EN

Stack Overflow用户
提问于 2022-02-11 17:17:52
回答 3查看 491关注 0票数 2

我已经看过很多线程的例子,如何做到这一点,问题是,我仍然不能做到这一点。

所有示例都有带有额外数据的表。例如,像这样的事情

代码语言:javascript
运行
复制
lines = {
  luaH_set = 10,
  luaH_get = 24,
  luaH_present = 48,
}

或者这个,

代码语言:javascript
运行
复制
obj = {
   { N = 'Green1'      },
   { N = 'Green'       },
   { N = 'Sky blue99'  }
}

我可以用几种语言编写代码,但我对Lua非常陌生,而且表对我来说真的很混乱。我似乎想不出如何调整示例中的代码,以便对一个简单的表进行排序。

这是我的桌子:

代码语言:javascript
运行
复制
local players = {"barry", "susan", "john", "wendy", "kevin"}

我想按字母顺序排列这些名字。我知道Lua桌子不能维持秩序,这就是让我困惑的地方。基本上,我关心的只是按字母顺序打印这些名字,但我觉得我需要正确地学习这些名字,并知道如何将它们按正确的顺序索引到一个新的表中。

我看到的例子如下:

代码语言:javascript
运行
复制
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

或者这个:

代码语言:javascript
运行
复制
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

对于一个简单的一维表,我完全不知道该如何做同样的事情。

有人能帮我理解一下吗?我知道,如果我能理解最基本的例子,我就能教自己这些更难的例子。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2022-02-11 17:37:41

代码语言:javascript
运行
复制
local players = {"barry", "susan", "john", "wendy", "kevin"}

-- sort ascending, which is the default
table.sort(players)
print(table.concat(players, ", "))

-- sort descending
table.sort(players, function(a,b) return a > b end)
print(table.concat(players, ", "))

原因如下:

您的表players是序列。

代码语言:javascript
运行
复制
local players = {"barry", "susan", "john", "wendy", "kevin"}

等于

代码语言:javascript
运行
复制
local players = {
  [1] = "barry",
  [2] = "susan",
  [3] = "john",
  [4] = "wendy",
  [5] = "kevin",
}

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

这样的表可以根据其值进行排序。Lua将简单地根据比较函数的返回值重新排列索引值对。默认情况下,这是

代码语言:javascript
运行
复制
function (a,b) return a < b end

如果您想要任何其他命令,则需要提供一个函数,如果元素ab的话,则需要提供returs true函数

读这个https://www.lua.org/manual/5.4/manual.html#pdf-table.sort

table.sort按给定的顺序对列表元素进行排序,从list1到list#list。

此示例不是“列表”或序列:

代码语言:javascript
运行
复制
lines = {
  luaH_set = 10,
  luaH_get = 24,
  luaH_present = 48,
}

这相当于

代码语言:javascript
运行
复制
lines = {
  ["luaH_set"] = 10,
  ["luaH_get"] = 24,
  ["luaH_present"] = 48,
}

它只有字符串作为键。它没有命令。您需要一个助手序列来将某些顺序映射到该表的元素。

第二个例子

代码语言:javascript
运行
复制
obj = {
   { N = 'Green1'      },
   { N = 'Green'       },
   { N = 'Sky blue99'  }
}

这相当于

代码语言:javascript
运行
复制
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时最重要的概念之一。表库的长度运算符、i对和许多函数只适用于序列。

票数 4
EN

Stack Overflow用户

发布于 2022-02-11 17:41:15

这是我的桌子:

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

我想按字母顺序排列这些名字。

你只需要table.sort(players)

我知道LUA表不能保持顺序。

Lua表(具有任意键的字典)中的字段顺序不被保留。

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

票数 3
EN

Stack Overflow用户

发布于 2022-02-11 17:40:56

为了消除与“不保持顺序”有关的混淆:没有保持顺序的是表中值的键,特别是字符串键,即当您将表用作字典而不是数组时。如果您编写了myTable = {orange="hello", apple="world"},那么您将键orange定义在键apple的左侧这一事实不会被存储。如果使用for k, v in pairs(myTable) do print(k, v) end枚举键/值,那么实际上在orange hello之前就会得到"apple" < "orange",因为"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代码排序:

代码语言:javascript
运行
复制
local players = {"barry", "susan", "john", "wendy", "kevin"}
table.sort(players)
-- players is now {"barry", "john", "kevin", "susan", "wendy"}

然而,如果你有混合的小写和大写条目,这将分崩离析,因为大写将在小写之前,因为有较低的ASCII代码,当然,它也不会正确地工作与非ASCII字符如umlauts (他们将最后)-这不是一个字典排序。

但是,您可以提供自己的排序函数,该函数接收参数(a, b),如果a位于b之前,则需要返回b。这里有一个修复小写/大写问题的示例,例如,在进行比较之前将其转换为大写:

代码语言:javascript
运行
复制
table.sort(players, function (a, b)
  return string.upper(a) < string.upper(b)
end)
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71084051

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档