Вот моя проблема: У меня есть массив строки, которая содержит данные, как то:Ruby: как отсортировать массив строки разбора содержимого
array = ["{109}{08} OK",
"{98} Thx",
"{108}{0.8}{908} aa",
"{8}{51} lorem ipsum"]
Я хотел бы отсортировать этот процесс сканирование массива «данные внутри» : здесь целые числа в фигурной скобке. Итак, окончательный массив должен быть таким:
array.custom_sort! => ["{8}{51} lorem ipsum",
"{98} Thx",
"{108}{0.8}{908} aa",
"{109}{08} OK"]
Есть ли хорошее решение для этого в Ruby? Или я должен воссоздать новый массив, который вставляет каждый анализируемый элемент?
EDIT:
я не упомянул о СНП приоритеты: Во-первых, сортировка на основе числа в фигурных скобках, до 3-х групп, но не может отсутствовать.
["{5}something",
"{61}{64}could",
"{}be", #raise an error or ignore it
"{54}{31.24}{0.2}write",
"{11}{21}{87}{65}here", #raise an error or ignore it
"[]or", #raise an error or ignore it
"{31}not"]
Если первые числа равны, то следует сравнить другие. Некоторые примеры:
"{15}" < "{151}" < "{151}{32}" < "{152}"
"{1}" < "{012}" < "{12}{-1}{0}" < "{12.0}{0.2}"
"{5}" < "{5}{0}" < "{5}{0}{1}"
Но если каждые числа равны, то строка сравнивается. Единственный символ, который создает проблему, - это пространство, которое должно быть после каждого другого «видимого» символа. Примеры:
"{1}a" < "{1}aa" < "{1} a" < "{1} a"
"{1}" < "{1}a " < "{1}a " < "{1}a a"
"{1}a" < "{1}ba" < "{1}b "
Я могу сделать это делать somethign, как это в пользовательском классе:
class CustomArray
attr_accessor :one
attr_accessor :two
attr_accessor :three
attr_accessor :text
def <=>(other)
if self.one.to_f < other.one.to_f
return -1
elsif self.one.to_f > other.one.to_f
return 1
elsif self.two.nil?
if other.two.nil?
min = [self.text, other.text].min
i = 0
until i == min
if self.text[i].chr == ' ' #.chr is for compatibility with Ruby 1.8.x
if other.text[i].chr != ' '
return 1
end
else
if other.text[i].chr == ' '
return -1
#...
self.text <=> other.text
end
end
Он отлично работает, но я очень разочарован кодирования в Рубине, как я кода в проекте C++. Вот почему я хотел бы знать, как использовать «настраиваемый сортировку в методе foreach» с более сложным способом сортировки (требуется разбор, сканирование, регулярное выражение), чем наивный, основанный на атрибуте содержимого.
Тщательное, как всегда , Хорошая работа. – DiegoSalazar
Это очень полезное объяснение, спасибо большое! Но для сравнения строк я забыл что-то сказать. Скажем: ["{42} foo", "{42} bar", "{42} world", "{42} hello"]. Трюк заключается в сравнении строки, символ пробела 'должен быть * после * alphanum, но в таблице ASCII это не так. Я видел в другом потоке (http://stackoverflow.com/questions/29808574/ruby-custom-string-sort), что я мог бы установить свой собственный «порядок символов». Возможно ли интегрировать эту функцию в элегантное решение? – Rikouchi
Я посмотрю на это позже сегодня. Тем временем я предлагаю вам отредактировать свой вопрос, чтобы добавить информацию в свой комментарий (а также исправить порядок '108' против' 109', если это необходимо). Поскольку дополнительная информация изменяет вопрос, вы должны сделать это ясно в редактировании. Часто это делается путем написания «Правка: я не упоминал ...», возможно, в конце вопроса. –