Rolf B: Intl.Collator und case-sensitivity

Hallo alle,

warum ergibt der Aufruf von compare in den beiden Vergleichspaaren jeweils den gleichen Wert? Bei einem case-sensitive Vergleich hätte ich erwartet, dass bei einem Wechsel der Schreibung des Anfangsbuchstabens die Reihenfolge wechselt. Wo ist sonst der Sinn eines case-sensitive Vergleichs?

const caseCollate = Intl.Collator("de-DE", { sensitivity: "case" });

console.log(caseCollate.compare("roh", "Rot"));   // -1 (erwarte 1)
console.log(caseCollate.compare("Roh", "rot"));   // -1

console.log(caseCollate.compare("rot", "Roh"));   // 1
console.log(caseCollate.compare("Rot", "roh"));   // 1 (erwarte -1)

Der erwartete Vorzeichenwechsel ergibt sich nur, wenn ich "roh" mit "Roh" vergleiche, d.h. der String case-insensitive gleich ist. Ist das irgendwo spezifiziert? Ich finde nichts, und die Texte bei ECMA-402 oder MDN geben das auch nicht her. Meine ich.

Rolf

--
sumpsi - posui - obstruxi
  1. Hm.

    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Collator „sagt“:

    Beachten Sie, dass die im obigen Code angezeigten Ergebnisse je nach Browser und Browserversion variieren können. Dies liegt daran, dass die Werte implementierungsspezifisch sind. Das heißt, die Spezifikation erfordert lediglich, dass die Vorher- und Nachher-Werte negativ und positiv sind.

    Ich vermute, die Regeln sind diese

    • 0 - Strings sind identisch.
    • 1 - Erster String steht in aufsteigender Sortierung nach zweitem String. (→ Umsortierung)
    • -1 - Erster String steht in aufsteigender Sortierung vor zweitem String.
    console.log(caseCollate.compare("roh", "Rot"));
    // -1 (erwarte 1)
    

    Warum? (Ich sortiere mal im Linux-Terminal ... Da die Länge der Strings identisch ist und die verwendeten Zeichen aus ASCII sind sollte das keine Probleme bereiten...)

    echo -e "roh\nRot" | sort
    roh
    Rot
    

    Keine Umsortierung: Hier wäre also tatsächlich -1 zu erwarten.

    console.log(caseCollate.compare("Rot", "roh"));
    // 1 (erwarte -1)
    
    echo -e "Rot\nroh" | sort
    roh
    Rot
    

    Umsortierung: Hier wäre also tatsächlich 1 zu erwarten.

    Wo ist sonst der Sinn eines case-sensitive Vergleichs?

    Ich vermute genau das: Der case-sensitive Vergleich ist Teil und „Abfallprodukt“ einer Sortierfunktion, wird von JS intern genutzt.


    Hinweis zum Forum: Bei Google findet fand ich soeben just Deinen gelöschten Beitrag...

    1. Hallo Raketenwilli,

      Dass 0 für gleich steht, < 0 für "Kleiner" und > 0 für "Größer", das ist dokumentiert und nicht mein Problem. Dass der konkrete positive oder negative Wert unspezifiziert ist, ist ebenfalls spezifiziert und ebenfalls nicht mein Problem. Das ist in anderen Sprachen auch so.

      Es geht mir um folgendes: Wenn ich einen klassischen case-sensitive Vergleich mit dem < Operator mache, ergibt sich "roh" > "Rot", weil die Kleinbuchstaben hinter den Großbuchstaben folgen.

      Aber der Collator macht das dem Anschein nach anders, er gibt beim case-sensitive Vergleich "roh" < "Rot" zurück, OBWOHL "r" > "R" ist. Das ist deshalb merkwürdig, weil das vertraute Verhalten doch so aussieht, dass für zwei Strings a, b mit a < b folgt, dass für zwei Präfixe dieser Strings mit Länge n die Relation left(a,n) <= left(b,n) gilt. Aber das ist beim Collator nicht der Fall.

      Hier gilt nämlich (mit caseFirst:"upper") "roh" < "Rot", aber "ro" > "Ro".

      Und ich wundere mich nun, ob ich eine Meise unter dem Pony der Platte habe, ob das eine Laune der Browser-Implementatoren ist oder ob sich das irgendwo in einer Spezifikation findet. ECMA-402 verweist da ständig auf Unicode, aber in dem Unicode Gestrüpp finde ich mich nicht zurecht.

      Ich frage doch bloß für einen Freund Wiki-Artikel…

      Rolf

      --
      sumpsi - posui - obstruxi
      1. ECMA-402 verweist da ständig auf Unicode, aber in dem Unicode Gestrüpp

        Hm. In https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Collator tauchen verdächtig viele Hinweise auf die Sortierung/Collation auf… und die hat „denklogisch“ mit dem Platz der von Dir untersuchten Zeichen in der Unicode-Tabelle nur eingeschränkt zu tun.

        Hint: Das Ding heißt ja nicht grundlos „Collator“.

        Zudem gibt/gäbe es ja noch weitere Sortierungen. Gerade auch im Computer.

        Nehmen wir die teutogermanischen Umlaute:

        • ä → als a oder nach z oder nach a und vor b einsortiert oder als „ae“ behandelt?

        Wenn ich einen klassischen case-sensitive Vergleich mit dem < Operator mache,

        Der macht „etwas ganz anderes“ denn der vergleicht eigentlich ord("a") mit ord("b"). Das Collator-Ding bearbeitet je nach Collation erstmal den String → replace("ä", "ae") und vergleicht dann sortOrd(collation ,"a") mit sortOrd(collation, "b")

        1. Hallo Raketenwilli,

          und die hat „denklogisch“ mit dem Platz der von Dir untersuchten Zeichen in der Unicode-Tabelle nur eingeschränkt zu tun.

          Stimmt, aber der Unicode-Standard enthält außer Zeichentabellen auch einen Sortieralgorithmus (UCA - Unicode Collation Algorithm) und Locale-abhängige Sortiergewichte. Jetzt, wo ich Dir das belegen will, finde ich dies und DAS ist die Antwort auf meine Eingangsfrage 😀. Danke schön 😉.

          Update: A-bär dann gibt's noch die Note 2 im ECMA-402-Standard, die empfiehlt, den UCA zu verwenden. Was nun wieder doof ist, denn damit ist es nicht garantiert, dass das beobachtete Verhalten überall gleich beobachtet wird 😕

          Rolf

          --
          sumpsi - posui - obstruxi
        2. @@Raketenwilli

          Nehmen wir die teutogermanischen Umlaute:

          • ä → als a oder nach z oder nach a und vor b einsortiert oder als „ae“ behandelt?

          Wörterbuchsortierung vs. Telefonbuchsortierung (Und die Österreicher machen’s wieder anders.)

          Oder nehmen wir das ch: als c + h behandelt oder als Digraph nach h einsortiert? Polnisch vs. tschechisch

          🖖 Живіть довго і процвітайте

          --
          Ad astra per aspera