Lua: 对 table 个带有多个点的数字进行排序

Lua: Sort table of numbers with multiple dots

我有 table 个这样的字符串:

{
    "1",
    "1.5",
    "3.13",
    "1.2.5.7",
    "2.5",
    "1.3.5",
    "2.2.5.7.10",
    "1.17",
    "1.10.5",
    "2.3.14.9",
    "3.5.21.9.3",
    “4”
}

并且想这样排序:

{
    "1",
    "1.2.5.7",
    "1.3.5",
    "1.5",
    "1.10.5",
    "1.17",
    "2.2.5.7.10",
    "2.3.14.9",
    "2.5",
    "3.5.21.9.3",
    "3.13",
    “4”
}

如何在 Lua 中对其进行排序?我知道 table.sort() 会被使用,我只是不知道用于比较的函数(第二个参数)。

table.sort 默认按升序排序。您不必再提供第二个参数。当您对字符串进行排序时,Lua 将逐个字符地比较字符串。因此,您必须实现一个排序函数,告诉 Lua 谁先出现。

I just don't know the function (second parameter) to use for comparison.

这就是人们写 Lua Reference Manual

的原因

table.sort (list [, comp])

Sorts the list elements in a given order, in-place, from list1 to list[#list]. If comp is given, then it must be a function that receives two list elements and returns true when the first element must come before the second in the final order, so that, after the sort, i <= j implies not comp(list[j],list[i]). If comp is not given, then the standard Lua operator < is used instead.

The comp function must define a consistent order; more formally, the function must define a strict weak order. (A weak order is similar to a total order, but it can equate different elements for comparison purposes.)

The sort algorithm is not stable: Different elements considered equal by the given order may have their relative positions changed by the sort.

想想你会如何用笔在纸上做。您将比较每个数字段。一旦一个段小于另一个段,您就会知道这个数字排在第一位。

因此,解决方案可能需要您获取字符串的那些段,将它们转换为数字,以便您可以比较它们的值...

根据您的要求,您可能想要 natural sort order. I described several possible solution as well as their impact on the results in a blog post.

最简单的解决方案可能如下所示(如下所示),但列出了 5 种不同复杂度的不同解决方案和结果:

function alphanumsort(o)
  local function padnum(d) return ("%03d%s"):format(#d, d) end
  table.sort(o, function(a,b)
    return tostring(a):gsub("%d+",padnum) < tostring(b):gsub("%d+",padnum) end)
  return o
end