array.sort_by { |s| [s.to_i, s[/(?<=-)\d+/].to_i, s.gsub(/\A.+-/,'')] }
#=> ["1mo-20-extra", "1mo-30-classic", "1mo-30-super", "1mo-40-classic", "1mo-110-super",
# "6mo-11-super", "6mo-21-super", "12mo-21-classic", "12mo-21-super"]
При сортировке массивов метод Arrays # <=> используется для упорядочивания пар массивов.См. Третий абзац документа для объяснения того, как это делается.
Массивы, используемые для сортировки, выглядят следующим образом.
array.each do |s|
puts "%-15s -> [%2d, %3d, %s]" % [s, s.to_i, s[/(?<=-)\d+/].to_i, s.gsub(/\A.+-/,'')]
end
1mo-30-super -> [ 1, 30, super]
1mo-40-classic -> [ 1, 40, classic]
1mo-30-classic -> [ 1, 30, classic]
1mo-110-super -> [ 1, 110, super]
1mo-20-extra -> [ 1, 20, extra]
6mo-21-super -> [ 6, 21, super]
6mo-11-super -> [ 6, 11, super]
12mo-21-classic -> [12, 21, classic]
12mo-21-super -> [12, 21, super]
(?<=-)
- это положительный взгляд за спиной .Требуется, чтобы совпадению предшествовал дефис./\A.+-/
соответствует началу строки, за которым следует один или несколько символов, за которыми следует дефис.Поскольку регулярные выражения по умолчанию жадные , совпадение заканчивается на втором дефисе.
Обратите внимание, что использование регулярных выражений необязательно:
array.sort_by { |s| [s.to_i, s[s.index('-')+1..-1].to_i, s[s.rindex('-')+1..-1]] }