我已经为自定义字符串实现了排序算法,该字符串表示田径赛事的时间或距离数据。下面是格式
'10:03.00 - 十分三秒或 10 英尺三英寸
排序的结果是,对于野外事件,最长的投掷或跳跃将是第一个元素,而对于跑步事件,最快的时间将是第一个元素。下面是我目前用于现场事件的代码。我没有发布running_event_sort
因为它与大于/小于交换的逻辑相同。虽然它有效,但它看起来过于复杂,需要重构。我愿意接受建议。任何帮助都会很棒。
event_participants.sort!{ |a, b| Participant.field_event_sort(a, b) }
class Participant
def self.field_event_sort(a, b)
a_parts = a.time_distance.scan(/'([\d]*):([\d]*).([\d]*)/)
b_parts = b.time_distance.scan(/'([\d]*):([\d]*).([\d]*)/)
if(a_parts.empty? || b_parts.empty?)
0
elsif a_parts[0][0] == b_parts[0][0]
if a_parts[0][1] == b_parts[0][1]
if a_parts[0][2] > b_parts[0][2]
-1
elsif a_parts[0][2] < b_parts[0][2]
1
else
0
end
elsif a_parts[0][1] > b_parts[0][1]
-1
else
1
end
elsif a_parts[0][0] > b_parts[0][0]
-1
else
1
end
end
end
这是一种情况#sort_by
可以极大地简化你的代码:
event_participants = event_participants.sort_by do |s|
if s =~ /'(\d+):(\d+)\.(\d+)/
[ $1, $2, $3 ].map { |digits| digits.to_i }
else
[]
end
end.reverse
在这里,我将相关时间解析为整数数组,并将它们用作数据的排序键。数组比较是逐项进行的,第一个是最重要的,因此效果很好。
您不做的一件事是将数字转换为整数,而您最有可能想做的事情。否则,你会遇到问题"100" < "2" #=> true
。这就是为什么我添加了#map
step.
另外,在你的正则表达式中,方括号周围\d
是不必要的,尽管您确实想转义句点,因此它不匹配所有字符。
我给出的代码与您给出的代码不匹配的一种方式是在一行不包含任何距离的情况下。您的代码会将它们与周围的行进行比较(如果排序算法假设相等性是传递的,这可能会给您带来麻烦。即a == b
, b == c
暗示a ==c
,您的代码并非如此:例如a = "'10:00.1"
, b = "frog"
, c="'9:99:9"
).
#sort_by
按升序排序,因此调用#reverse
会将其更改为降序。#sort_by
还具有仅解析一次比较值的优点,而您的算法必须为每次比较解析每一行。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)