ruby中的版本排序(使用alphas、betas等)

ruby中的版本排序(使用alphas、betas等),ruby,sorting,natural-sort,version-sort,Ruby,Sorting,Natural Sort,Version Sort,如何对Ruby中的版本列表进行排序?我见过关于自然排序的东西,但这是一个更进一步 输入是一组字符串,如下所示: input = ['10.0.0b12', '10.0.0b3', '10.0.0a2', '9.0.10', '9.0.3'] 我几乎可以用宝石做到: 问题:10.0.0b3排序在10.0.0b12之后;10.0.0b3应该是第一位 有人有办法吗?其他语言也很有用 如果您将其解释为“按每段数字排序”,则您可以使用以下方法处理上述示例输入: input.map{ |ver| ver.

如何对Ruby中的版本列表进行排序?我见过关于自然排序的东西,但这是一个更进一步

输入是一组字符串,如下所示:

input = ['10.0.0b12', '10.0.0b3', '10.0.0a2', '9.0.10', '9.0.3']
我几乎可以用宝石做到:

问题:10.0.0b3排序在10.0.0b12之后;10.0.0b3应该是第一位

有人有办法吗?其他语言也很有用

如果您将其解释为“按每段数字排序”,则您可以使用以下方法处理上述示例输入:

input.map{ |ver| ver.split(%r{[^\d]+}).map(&:to_i) }.zip(input).sort.map(&:last)
=> ["9_0", "9_1", "10_0b3", "10_0b12"]
就是

  • 对于每个值,例如
    10\u 0b3
  • 按任意长度的非数字字符拆分,例如
    [“10”、“0”、“3”]
  • 将每个数字段转换为整数,例如
    [10,0,3]
  • 带原始输入的zip,产生
    [[10,0,12],“10_0b12”],[[10,0,3],“10_0b3”],[[9,0],“9_0”],[[9,1],“9_1”]
  • 根据
    [10,0,3]<[10,0,12]
  • 获取每个元素的最后一个值,它是对应于每个已处理的可排序值的原始输入值
现在,这仍然是非常定制的——像“9_0a”和“9_0b”这样简单的版本号将不会被处理,两者都将看起来是[9,0]——因此您可能需要进一步调整它,但希望这会让您走上一条可行的道路

编辑:上面的示例输入已更改,因此我更改了正则表达式,以确保数字匹配是贪婪的,并且仍然有效:

irb(main):018:0> input = ['10.0.0b12', '10.0.0b3', '9.0.10', '9.0.3']
=> ["10.0.0b12", "10.0.0b3", "9.0.10", "9.0.3"]
irb(main):025:0> input.map{ |ver| ver.split(%r{[^\d]+}).map(&:to_i) }.zip(input).sort.map(&:last)
=> ["9.0.3", "9.0.10", "10.0.0b3", "10.0.0b12"]

Ruby随Gem类一起提供,它了解以下版本:

ar = ['10.0.0b12', '10.0.0b3', '10.0.0a2', '9.0.10', '9.0.3']

p ar.sort_by { |v| Gem::Version.new(v) }
# => ["9.0.3", "9.0.10", "10.0.0a2", "10.0.0b3", "10.0.0b12"]

在使用NuGet的特定情况下,您希望通过NuGet自己独特的Ruby代码版本控制方案来解析、比较或排序,现在有以下内容:


我创建它是为了解决这个问题。NuGet的版本号有点奇怪,它们是SemVer的超集,也允许使用4个组件而不是3个组件。

这些是非常非典型的版本字符串。你不可能找到现成的解决方案;你应该自己写。我改为使用语义版本控制。这更为典型。@MusashiAharon这并不是完全的语义版本控制。为此,您希望在
b12
b3
等前面加一个
-
.True。使用连字符时,自然排序效果很好,但这种几乎是半自动的系统仍然很常见。这确实有帮助,但beta并不是唯一可能的后缀。我们也可以有像“10.0.0a2”这样的alpha或像“10.0.0rc1”这样的候选版本。如果这些与其他并排排列,排序就会中断。很好。不管它值多少--看起来这个只按字母顺序处理“alpha”和“beta”。也就是说,
['9.0.10rc2'、'9.0.10'、'9.0.10rc1'、'9.0.10a'、'9.0.10test']
产生
[“9.0.10rc1”、“9.0.10rc2”、“9.0.10test”、“9.0.10”]
。这应该足够了,因为“alpha/beta/pre-release/rc/release”碰巧是按字母顺序排列的,但如果您的数据与字母顺序相差太远,则可能会很奇怪。它的工作原理非常有趣:
ar = ['10.0.0b12', '10.0.0b3', '10.0.0a2', '9.0.10', '9.0.3']

p ar.sort_by { |v| Gem::Version.new(v) }
# => ["9.0.3", "9.0.10", "10.0.0a2", "10.0.0b3", "10.0.0b12"]