在ruby中使用数字和字符对字符串数组进行排序
我有一个给定字符串的数组在ruby中使用数字和字符对字符串数组进行排序,ruby,sorting,Ruby,Sorting,我有一个给定字符串的数组 array = [ "1mo-30-super", "1mo-40-classic", "1mo-30-classic", "1mo-110-super", "1mo-20-extra", "6mo-21-super", "6mo-11-super", "12mo-21-classic", "12mo-21-super" ] 如何对数组进行排序,使其按数字顺序排列,然后按字母顺序排列,使数组显示如下: array = [ "1m
array = [
"1mo-30-super",
"1mo-40-classic",
"1mo-30-classic",
"1mo-110-super",
"1mo-20-extra",
"6mo-21-super",
"6mo-11-super",
"12mo-21-classic",
"12mo-21-super"
]
如何对数组进行排序,使其按数字顺序排列,然后按字母顺序排列,使数组显示如下:
array = [
"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"
]
您可以链接多个
#sort
方法调用,每个调用按字符串的不同部分排序(从优先级最小的一个开始):
array.sort{a,b | a.match(/-(.*)$/)[1]b.match(/-(.*)-/)[1]}按最后一个元素排序('classic',super'))
.sort{a,b{a.match(/-(\d+)-/)[1]。to|i b.match(/-(\d+)-/)[1]。to|i}按破折号之间的数字排序
.sort{a,b | a.to_i b.to_i}按初始数字排序
=>[“1mo-20-extra”,
“1mo-30-classic”,
“1mo-30-super”,
“1mo-40-classic”,
“1mo-110-super”,
“6mo-11-super”,
“6mo-21-super”,
“12mo-21-super”,
“12mo-21-classic”]
您可以链接多个#sort
方法调用,每个调用按字符串的不同部分排序(从优先级最小的一个开始):
array.sort{a,b | a.match(/-(.*)$/)[1]b.match(/-(.*)-/)[1]}按最后一个元素排序('classic',super'))
.sort{a,b{a.match(/-(\d+)-/)[1]。to|i b.match(/-(\d+)-/)[1]。to|i}按破折号之间的数字排序
.sort{a,b | a.to_i b.to_i}按初始数字排序
=>[“1mo-20-extra”,
“1mo-30-classic”,
“1mo-30-super”,
“1mo-40-classic”,
“1mo-110-super”,
“6mo-11-super”,
“6mo-21-super”,
“12mo-21-super”,
“12mo-21-classic”]
您正在寻找一种“自然”排序,其中数字子字符串将作为数字进行比较,而非数字部分将作为字符串进行比较。非常方便,Ruby中的数组会逐个元素进行比较,并且格式相当规则,因此您可以通过调用#sort_by
和一些混乱来将“12mo-21-classic”
转换为[12,'mo-',21,'-classic']
。比如说:
# This is a bit complicated so we'll give the logic a name.
natural_parts = ->(s) { s.match(/(\d+)(\D+)(\d+)(\D+)/).to_a.drop(1).map.with_index { |e, i| i.even?? e.to_i : e } }
array.sort_by(&natural_parts)
您正在寻找一种“自然”排序,其中数字子字符串将作为数字进行比较,而非数字部分将作为字符串进行比较。非常方便,Ruby中的数组会逐个元素进行比较,并且格式相当规则,因此您可以通过调用#sort_by
和一些混乱来将“12mo-21-classic”
转换为[12,'mo-',21,'-classic']
。比如说:
# This is a bit complicated so we'll give the logic a name.
natural_parts = ->(s) { s.match(/(\d+)(\D+)(\d+)(\D+)/).to_a.drop(1).map.with_index { |e, i| i.even?? e.to_i : e } }
array.sort_by(&natural_parts)
考虑到每个字符串以一个或两个数字开头,连字符之间有两个或三个数字,请更具体地说明数字排序。同样地,考虑到两个地方也有字母串,你说的第二个排序标准是什么意思?我想对它进行排序,所以第一部分按数字排序,然后所有第一个数字相同的部分,第二部分按数字排序,然后,最后一部分中的字符串按字母顺序排序。考虑到每个字符串以一个或两个数字开头,连字符之间有两个或三个数字,请更具体地说明数字排序。类似地,考虑到两个地方也有字母串,你说的第二个排序标准是什么意思?我想对它进行排序,以便第一部分按数字排序,然后对所有第一个数字相同的部分按数字排序,第二部分按数字排序,最后一部分中的字母按字母排序。
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"]
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]
array.sort_by { |s| [s.to_i, s[s.index('-')+1..-1].to_i, s[s.rindex('-')+1..-1]] }