Sortieren von UTF-8-Zeichenfolgen in RoR
Ich versuche herauszufinden, eine 'richtige' Art und Weise der Sortierung für UTF-8 strings in Ruby on Rails.
In meiner Anwendung, ich habe eine select-box, die gefüllt ist mit den Ländern. Als meine Anwendung ist lokalisiert, die jeweils vorhandenen Gebietsschema hat eine Ländern.yml-Datei, die sich einer Land-id den lokalisierten Namen für das Land. Ich kann nicht Sortieren der strings manuell in der yml-Datei, weil ich brauche die ID um konsistent über alle Gebietsschemas.
Was ich getan habe ist, erstellen Sie eine ascii_name
Methode, die verwendet die unidecode
Juwel konvertieren mit Akzent und nicht-lateinische Zeichen in Ihre ascii-äquivalente (zum Beispiel, "Afeganistão" geworden wäre "Afeganistao"), und dann Sortieren Sie auf, dass:
require 'unidecode'
class Country
def ascii_name
Unidecoder.decode(name).gsub("[?]", "").gsub(/`/, "'").strip
end
end
Country.all.sort_by(:&ascii_name)
Jedoch gibt es offensichtliche Probleme mit diesem:
- Es nicht richtig Sortieren, nicht-lateinische Sprachen, da kann es nicht sein, eine direkte Analog-lateinischen Zeichen.
- Es macht keinen Unterschied zwischen einem Brief und alle mit Akzent Formen, die Buchstaben (also z.B. A und Ä werden austauschbar)
Kennt jemand eine bessere Möglichkeit, ich könnte die Art meiner strings?
Du musst angemeldet sein, um einen Kommentar abzugeben.
http://github.com/grosser/sort_alphabetical
Dieser Edelstein sollte helfen. Es fügt
sort_alphabetical
undsort_alphabetical_by
Methoden zu Enumberable.utf8_polish_ci
. Wenn Sie möchten, Sortieren Sie Sie in Ruby, befolgen Sie diese Antwort: stackoverflow.com/a/5472046/304175Ruby peforms string-Vergleich auf der Grundlage der byte-Werte der Zeichen:
Richtig zu Sortieren, strings, je nach Gebietsschema, die ffi-icu gem verwendet werden könnten:
Als alternative:
Update um Zu testen, wie sollten strings Sortieren nach Gebietsschema Regeln des ICU-Projekts bietet dieses nette tool.
Die einzige Lösung, die ich gefunden habe bisher ist die Verwendung
ActiveSupport::Inflector.transliterate(string)
zu ersetzen, die unicode-Zeichen mit ASCII und Sortieren:Nun, das problem ist nur, dass diese so ausgleicht, dass "ä" mit "a" (DIN 5007-1) und ich am Ende mit "Ägypten" vor "Albanien" ich würde erwarten, dass es die andere Weise herum. Zum Glück ist die transliteration ist konfigurierbar über gewusst wie: ersetzen von Zeichen.
Siehe Dokumentation: http://api.rubyonrails.org/classes/ActiveSupport/Inflector.html#method-i-transliterate
de_DE.UFT8
) ist es normal, dass Ägypten kommt vor Albanien.ActiveSupport::Inflector
es nicht unterstützt standardmäßig.Gibt es ein paar Wege zu gehen. Sie können konvertieren möchten, der in UTF-strings in hex-strings und Sortieren Sie dann:
oder nutzen Sie die iconv-Bibliothek. Lesen Sie es und verwenden Sie es als angemessen (von dzone):
Die einzige funktionierende Lösung die ich bisher gefunden (zumindest für Ruby 1.8, weil Ruby 1.9 behandeln soll, die Unicode-besser) ist Unicode von Yoshida, Masato,. Finden Sie Unicode.strcmp Methode gibt.
EDIT: Sorry, diese Lösung verwendet NFD-ZERLEGUNG als auch mit allen seinen Einschränkungen.
Was Sie zu tun versuchen, ist eine sehr unordentliche Angelegenheit werden. Es gibt keine Möglichkeit, das zu tun transparente transliteration auf alle Unicode-Zeichen, weil der Sinn des Digraphen ändert sich von Ort zu Ort, und Streicher kann wachsen RIESIGE (wenn sagen Sie ersetzen 10 chinesische Symbole mit Ihren phonetischen äquivalente). Gehen Sie nicht dort.
Warum willst du transliterierte Namen in den ersten Platz? Für URLs? Browser die Verarbeitung von Unicode-URLs anständig nun, so Sie sind, erfinden Sie ein großes problem aus der Luft gegriffen. Wenn Sie brauchen, IDs, Vorverarbeiten Ihrer Listen, um eine stabile numerische ID, die pro Land und zu verwenden, dass als Bezeichner. Oder speichern Sie den englischen Namen des Landes als identitifer (Sie können download-locale-aware ISO-Land Listen kostenlos).
Wenn Sie wirklich wollen, eine gute Transkription für Unicode (und das ist nicht das, was Sie wollen, in diesem Fall) die IBM ICU-Bibliotheken, es ist ein schlafender Edelstein für Sie.
Haben Sie versucht, Zugriff auf die
mb_chars
Methode für jedes Land strings?mb_chars
ist ein proxy, der ActiveSupport fügt hinzu, definiert Unicode-sichere Versionen von allenString
Methoden. Wenn der Komparator ist Unicode-kompatibel ist dann die Sortierung sollte korrekt funktionieren.mb_chars
- Dokumentation