Сортировка значений с использованием определенной сортировки в Ruby / Rails
можно ли сортировать массив значений с помощью определенной сортировки в Ruby? Мне нужно сортировать по сортировки da_DK.
дан массив %w(Aarhus Aalborg Assens)
Я хотел бы иметь ['Assens', 'Aalborg', 'Aarhus']
назад, который является правильным порядком на датском языке.
стандартный метод сортировки
%w(Aarhus Aalborg Assens).sort
возвращает что-то, что выглядит как порядок ascii (по крайней мере, не датский порядок):
["Aalborg", "Aarhus", "Assens"]
среда работает как Snow Leopard, так и linux ruby 1.9.2 и Rails 3.0.5.
2 ответов
по данным Википедия:
в датском и Норвежском алфавитах те же дополнительные гласные, что и в шведском (см. ниже), также присутствуют, но в другом порядке и с разными символами (..., X, Y, Z, Æ, Ø, Å). Кроме того," Aa "сопоставляется как эквивалент"Å". Датский алфавит традиционно рассматривал " W "как вариант" V", но сегодня" W " считается отдельной буквой."
это скинуть рассортировать.
сделайте это, чтобы исправить проблему:
names = %w(Aarhus Aalborg Assens)
names.sort_by { |w| w.gsub('Aa', 'Å') } # => ["Assens", "Aalborg", "Aarhus"]
и что-то подобное для других букв, которые имеют сложные комбинации символов для преобразования в один символ.
причина этого работает sort_by
тут Преобразование Шварца, поэтому он фактически сортируется по возвращаемому значению, возвращаемому из блока, которое в данном случае является именем с "Aa", замененным на "Å". Замена является временной и отбрасывается, когда массив отсортирован.
sort_by
очень мощный, но имеет некоторые накладные расходы. Для простой сортировки вы должны использовать sort
потому что его быстрее. Для сортов, где вы сравниваете два простых значения на верхнем уровне объекта, тогда становится ясно, следует ли использовать sort
или sort_by
. Если вам нужно выполнить более сложные вычисления или покопаться в объекте, то sort_by
может оказаться быстрее. Нет реального жесткого и быстрого способа узнать, что лучше, поэтому я настоятельно рекомендую тестирование с бенчмарком, если вам нужно сортировать большие массивы или иметь дело с объектами, потому что разница может быть большой, а иногда sort
может быть лучшим выбором.
EDIT:
Ruby сам по себе не собирается делать то, что вы хотите, потому что он не знает порядка сортировки каждого символа, установленного там. Есть обсуждение о включении IBM ICU это объясняет, почему это так. Если вам нужны способности ICU, вы можете посмотреть в ICU4R. Я не играл с ним, но это звучит как ваше единственное реальное решение в Ruby.
вы можете сделать что-то с базой данных, такой как Postgres. Они поддерживают различные параметры сортировки, но обычно заставляют объявлять параметры сортировки при создании базы данных... или, может быть, это когда создается таблица... прошло много времени с тех пор, как я создал новую таблицу. В любом случае, это был бы вариант, хотя и болезненный.
нашел ИФО-язык на GitHub и это решает мою проблему, насколько я могу видеть.
Он позволяет следующий код:
FFILocale::setlocale FFILocale::LC_COLLATE, 'da_DK.UTF-8'
%w(Aarhus Aalborg Assens).sort { |a,b| FFILocale::strcoll(a, b) }
, который возвращает правильный результат:
=> ["Assens", "Aalborg", "Aarhus"]
Я еще не исследовал производительность, но он вызывает собственный код, поэтому он должен быть быстрее, чем код замены символов Ruby...
обновление
Это не идеально : (он не работает должным образом на Snow Leopard-это кажется, что функция strcoll нарушена на OS X и была в течение некоторого времени. Это раздражает меня, но основная платформа для развертывания-linux, где она работает, поэтому это мое предпочтительное решение.