问题描述
给出以下数组:
y = %w[A1 A2 B5 B12 A6 A8 B10 B3 B4 B8]
=> ["A1", "A2", "B5", "B12", "A6", "A8", "B10", "B3", "B4", "B8"]
预期的排序数组为:
=> ["A1", "A2", "A6", "A8", "B3", "B4", "B5", "B8", "B10", "B12"]
使用以下(原始)排序,我得到:
Using the following (vanilla) sort, I get:
irb(main):2557:0> y.sort{|a,b| puts "%s <=> %s = %s\n" % [a, b, a <=> b]; a <=> b}
A1 <=> A8 = -1
A8 <=> B8 = -1
A2 <=> A8 = -1
B5 <=> A8 = 1
B4 <=> A8 = 1
B3 <=> A8 = 1
B10 <=> A8 = 1
B12 <=> A8 = 1
A6 <=> A8 = -1
A1 <=> A2 = -1
A2 <=> A6 = -1
B12 <=> B3 = -1
B3 <=> B8 = -1
B5 <=> B3 = 1
B4 <=> B3 = 1
B10 <=> B3 = -1 # this appears to be wrong, looks like 1 is being compared, not 10.
B12 <=> B10 = 1
B5 <=> B4 = 1
B4 <=> B8 = -1
B5 <=> B8 = -1
=> ["A1", "A2", "A6", "A8", "B10", "B12", "B3", "B4", "B5", "B8"]
...这显然不是我想要的.我知道我可以先尝试对alpha进行拆分,然后对数字进行排序,但似乎我不必这样做.
...which is obviously not what I desire. I know I can attempt to split on the alpha first and then sort the numerical, but it just seems like I shouldn't have to do that.
可能的警告:我们暂时仍在使用Ruby 1.8.7 :(但是Ruby 2.0.0也在做同样的事情.我在这里缺少什么?
Possible big caveat: we're stuck using Ruby 1.8.7 for now :( But even Ruby 2.0.0 is doing the same thing. What am I missing here?
建议?
推荐答案
您正在对字符串进行排序.字符串的排序方式类似于字符串,而不是数字.如果要像数字一样排序,则应该对数字而不是字符串进行排序.字符串'B10'
在字典上小于字符串'B3'
,这不是Ruby独有的东西,甚至不是编程所独有的东西,这就是字典上排序文本的方式几乎在任何地方都有效,无论是在编程,数据库,词典,字典,电话簿等.
You are sorting strings. Strings are sorted like strings, not like numbers. If you want to sort like numbers, then you should sort numbers, not strings. The string 'B10'
is lexicographically smaller than the string 'B3'
, that's not something unique to Ruby, that's not even something unique to programming, that's how lexicographically sorting a piece of text works pretty much everywhere, in programming, databases, lexicons, dictionaries, phonebooks, etc.
您应该将字符串分成数字和非数字部分,并将数字部分转换为数字.数组排序是按字典顺序进行的,因此最终将完全正确地进行排序:
You should split your strings into their numerical and non-numerical components, and convert the numerical components to numbers. Array sorting is lexicographic, so this will end up sorting exactly right:
y.sort_by {|s| # use `sort_by` for a keyed sort, not `sort`
s.
split(/(\d+)/). # split numeric parts from non-numeric
map {|s| # the below parses numeric parts as decimals, ignores the rest
begin Integer(s, 10); rescue ArgumentError; s end }}
#=> ["A1", "A2", "A6", "A8", "B3", "B4", "B5", "B8", "B10", "B12"]
这篇关于红宝石字母数字排序无法正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!