红宝石中的版本排序(使用alphas,beta等)

时间:2015-10-22 20:10:10

标签: ruby sorting natural-sort version-sort

如何在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应该是第一个。

任何人都有办法吗?其他语言也很有用!

3 个答案:

答案 0 :(得分:23)

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

答案 1 :(得分:3)

如果您将其解释为"按每个数字段"排序,那么您将在上面处理您的示例输入:

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]
  • zip with original input,yield [[[10, 0, 12], "10_0b12"], [[10, 0, 3], "10_0b3"], [[9, 0], "9_0"], [[9, 1], "9_1"]]
  • 依据[10,0,3] < [10,0,12]
  • 排序
  • 获取每个元素的最后一个值,这是与每个已处理的可排序值
  • 对应的原始输入值

现在已经获得批准,这仍然非常自定义 - 版本号简单如&#34; 9_0a&#34; vs&#34; 9_0b&#34;不会被处理,两者似乎都是[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"]

答案 2 :(得分:0)

在特定的情况下,如果您正在使用NuGet,并且要根据Ruby代码中NuGet特有的自己的版本控制方案来解析,比较或排序,则现在有以下内容:

https://rubygems.org/gems/nuget_versions

我专门创建了它来解决此问题。 NuGet的版本号有些奇怪,它们是SemVer的超集,它还允许使用4个组件而不是3个组件。