Это ситуация, когда #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
.
Кроме того, в вашем регулярном выражении квадратные скобки вокруг \d
не нужны, хотя вы хотите избежать точки, чтобы она не соответствовала всем символам.
Один из способов, которым код, который я дал, не совпадает с кодом, который вы дали, - это ситуация, когда линия не содержит никаких расстояний. Ваш код будет сравнивать их как равные окружающим строкам (что может привести к неприятностям, если алгоритм сортировки предполагает, что равенство транзитивно. То есть a == b
, b == c
подразумевает a ==c
, что не относится к вашему коду: для пример a = "'10:00.1"
, b = "frog"
, c="'9:99:9"
).
#sort_by
сортируется в порядке возрастания, поэтому вызов #reverse
изменит его в порядке убывания. #sort_by
также имеет то преимущество, что анализирует только значения сравнения один раз, тогда как ваш алгоритм должен будет анализировать каждую строку для каждого сравнения.