Ruby中的版本排序(使用alpha,beta等)

jv2fixgn  于 2023-08-04  发布在  Ruby
关注(0)|答案(3)|浏览(112)

如何在Ruby中对版本列表进行排序?我看过一些关于自然排序的东西,但这是超越自然排序的一步。
输入是一串字符串,如下所示:

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

字符串
我几乎可以用naturally gem做到这一点:

require 'naturally'
Naturally.sort(input)
=> ["9.0.3", "9.0.10", "10.0.0a2", "10.0.0b12", "10.0.0b3"]


问题:10.0.0b3排序在10.0.0b12之后; 10.0.0b3应该是第一个。
有人有办法吗?其他语言也很有用!

rekjcdws

rekjcdws1#

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"]

字符串

toiithl6

toiithl62#

如果您将其解释为“按每个数字段排序”,则以下内容将处理上面的示例输入:

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

字符串
也就是说,

  • 对于每个值,例如10_0b3
  • 分割任意长度的非数字字符,例如["10","0","3"]
  • 将每个数字段转换为整数,例如[10,0,3]
  • 使用原始输入进行压缩,得到[[[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"]

e3bfsja2

e3bfsja23#

在特定情况下,您正在使用NuGet并希望从Ruby代码中解析,比较或按NuGet特有的版本化方案排序,现在有以下内容:
https://rubygems.org/gems/nuget_versions
我是专门为解决这个问题而设计的。NuGet的版本号有点奇怪,它们是SemVer的超集,也允许使用4个组件而不是3个。

相关问题