Sortierung CompareMethod.Binary vs CompareMethod.Text

  • VB.NET

Es gibt 11 Antworten in diesem Thema. Der letzte Beitrag () ist von RodFromGermany.

    Sortierung CompareMethod.Binary vs CompareMethod.Text

    Hi,
    wir wollten ein Tool für ein Verzeichnisvergleich schreiben und haben folgende Merkwürdigkeit dabei gefunden:
    ursprünglich wollten wir den einfachen Vergleich s1 < s2 nutzen, bekamen dabei aber fehlerhafte Ausgabe, letztlich führte dann der Stringvergleich mit CompareMethod.Text zum Ziel.
    Aber zur Frage: warum liefert denn CompareMethod.Text andere Werte als CompareMethod.Binary, wenn man keine Buchstaben vergleicht ?

    Im unserem speziellen Fall wird der Unterstrich unterschiedlich einsortiert:

    Compare '1' to '_'
    CompareMethod.Text : 1
    CompareMethod.Binary : -1
    a1 < s2: True
    Willkommen im Forum.

    Entsprechend der Doku:

    Microsoft schrieb:

    Binary
    Resultiert in Zeichenfolgenvergleichen basierend auf einer Sortierreihenfolge, die sich von den internen binären Darstellungen der Zeichen ableitet.

    Diese Art von Vergleich ist besonders hilfreich, da die Zeichenfolgen Zeichen enthalten können, die nicht als Text interpretiert werden. In diesem Fall sollten Sie Vergleiche nicht alphabetischen Äquivalenzen, z. B. Groß-/Kleinschreibung vorziehen.

    Text
    Führt zu einem Zeichenfolgenvergleich basierend auf einer schreibungsunabhängigen Textsortierreihenfolge, die durch das Gebietsschema des Systems bestimmt wird.

    Diese Art von Vergleich ist nützlich, wenn die Zeichenfolgen nur Textzeichen enthalten und Sie nur anhand alphabetischer Äquivalenzen z. B. Groß-/Kleinschreibung oder eng verwandter Buchstaben vergleichen möchten. Sie könnten zum Beispiel A und a als gleich ansehen und Ä und ä, die vor B und b kommen.

    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    von VaporiZed gefundenen Fehler beseitigt

    @J.Kannengiesser Willkommen im Forum. :thumbup:
    Schau Dir mal diesen Artikel an:
    learn.microsoft.com/en-us/dotn…/option-compare-statement
    An welcher Stelle hast Du die Compare-Methoden vorgegeben?
    Wenn ich diese in den Projekt-Eigenschaften ändere, ändert sich der Wert von res2:

    VB.NET-Quellcode

    1. Dim s1 = "1"
    2. Dim s2 = "_"
    3. Dim res1 = String.Compare(s1, s2) ' bleibt gleich
    4. Dim res2 = s1 < s2 ' ändert sich
    Wenn Du

    VB.NET-Quellcode

    1. Dim res1 = String.Compare(s1, s1)
    verwendest, bist Du auf der sicheren Seite.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „RodFromGermany“ ()

    RodFromGermany schrieb:

    String.Compare(s1, s1)
    Text mit sich selbst vergleichen?
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    die o.g. Themen dazu hatte ich alle bereits gelesen.
    Die Frage ist warum ein Unterstrich im Vergleich zu einer Zahl / Buchstabe bei compareMethod.binary größer ist und bei ist und bei compareMethod.Text kleiner ?
    Wo ist das denn dokumentiert bzw. nachzulesen ?

    Im Explorer wird das "_" vor den Zahlen einsortiert - also wie bei compareMethod.Text.

    Hinzu kommt dann auch noch die "numerische" Sortierung im Explorer : "1x" < "2x" < "11x" -
    um die gleiche Sortierung zu bekommen, kann man den Array.Sort erst einmal mit eigener Sortierung erweitern ...

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „J.Kannengiesser“ ()

    @VaporiZed unbeabsichtigte C&P-Bremse, im Code war alles richtig. ;)
    @J.Kannengiesser Gebietsschema des Systems ist hier das Zauberwort.
    Wenn Du dem Compare()-Befehl eine Culture-Information mit gibst, ist es vorstellbar,
    dass ein Vergleich zweier (wohl ausgesuchter) Zeichen mit verschiedenen Kulturen unterschiedliche Ergebnisse liefert
    (das habe ich nicht getestet!).
    ====
    Wenn Du numerische Werte in Strings korrekt sortieren willst, brauchst Du einen speziellen Comparer:
    Array.Sort für DirectoryInfo.GetFiles nach Datum
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    J.Kannengiesser schrieb:

    Die Frage ist warum ein Unterstrich im Vergleich zu einer Zahl / Buchstabe bei compareMethod.binary größer ist und bei ist und bei compareMethod.Text kleiner ?
    Wo ist das denn dokumentiert bzw. nachzulesen ?
    ja, weiss ich auch nicht.
    Option Compare Text / Binary verwende ich eh nie, eben weil die Sortierreihenfolge obskur definiert ist.
    Ich verwende immer String.Compare(s1, s2, StringComparer).
    und zwar entweder mit StringComparer.Ordinal oder mit StringComparer.OrdinalIgnoreCase
    Diese beiden sind die einzigen, bei denen ich die Sortier-Reihenfolge jedes Zeichens nachvollziehen kann - per Convert.ToInt32(c As Char).
    Hallo zusammen.
    Zu RodFromGermanys Post »Wenn Du dem Compare()-Befehl eine Culture-Information mit gibst, ist es vorstellbar, dass ein Vergleich zweier (wohl ausgesuchter) Zeichen mit verschiedenen Kulturen unterschiedliche Ergebnisse liefert« kann ich etwas beisteuern.
    Ich habe hier mal vor langer Zeit einen Thread eröffnet, in dem es darum ging, dass Code-Analyse-Tools meckern, wenn man keine CultureInfo mitgibt. Ein Test hat ergeben, dass es tatsächlich Probleme mit dem türkischen İ geben kann (man beachte, dass es ein Großbuchstabe ist und trotzdem einen Punkt drüber hat) – aber auch nur da.

    J.Kannengiesser schrieb:

    Die Frage ist warum ein Unterstrich im Vergleich zu einer Zahl / Buchstabe bei compareMethod.binary größer ist und bei ist und bei compareMethod.Text kleiner ?
    Wo ist das denn dokumentiert bzw. nachzulesen ?

    Im Explorer wird das "_" vor den Zahlen einsortiert - also wie bei compareMethod.Text
    Compare-Method Binary ist dasselbe wie mit StringComparison.Ordinal zu sortieren. Und da hat der _ die Nummer 95 und die 1 ist Nummer 49.
    Compare-Method Text wird kulturabhängig sein. Ich gehe auch mal davon aus, dass Windows in anderen Kulturen anders seinen Explorer sortiert.

    Haudruferzappeltnoch schrieb:

    Und da hat der _ die Nummer 95 und die 1 ist Nummer 49.
    Ich gehe mal davon aus, dass Du mit "Nummer" den ASCII-Code meinst. ;)
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    Haudruferzappeltnoch schrieb:

    Compare-Method Binary ist dasselbe wie mit StringComparison.Ordinal zu sortieren. Und da hat der _ die Nummer 95 und die 1 ist Nummer 49.
    Compare-Method Text wird kulturabhängig sein. Ich gehe auch mal davon aus, dass Windows in anderen Kulturen anders seinen Explorer sortiert.
    zunächstmal (das stört mich schon den ganzen Thread): Wir reden hier von Option Compare Text/Binary - oder?
    Weil Compare-Method Binary, Compare-Method Text - soweit ich weiss gibts das garnet.
    Es gibt allerdings StringComparer, und StringComparisons, daher ist wichtig, diese ähnlichen Worte auseinanderzuhalten, und richtig zu verwenden.

    Ansonsten: Is wie HDZ sagt - gugge learn.microsoft.com/en-us/dotn…k(DevLang-VB)%26rd%3Dtrue
    (einfach im VS den Cursor auf Compare setzen und F1 drücken - siehe VisualStudio richtig nutzen (Google ist nicht deine Mami))

    Nachtrag: Also sowas macht mich ja ganz wuschig:

    VB.NET-Quellcode

    1. Option Compare Text
    2. '...
    3. Dim b = "ä" < "b" 'True
    4. b = "ä"c < "b"c 'False
    D.h. der String "ä" ist kleiner als der String "b".
    Aber der Char "ä"c ist grösser als der Char "b"c!
    Also dieselben Lettern haben als einzelnes Zeichen (Char) eine andere Sortierung, als als String ?(
    Deswegen Comparison.Ordinal, da ist die Sortierreihenfolge einheitlich.

    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „ErfinderDesRades“ ()

    ErfinderDesRades schrieb:

    soweit ich weiss gibts das garnet.
    VB-Projekt, Projekteigenschaften - Kompilieren, neben Strict, Explizit und Infer.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!