René: Stringsortierung von Javascript und MySQL

Hallo,
also ich habe da ein ziemlich komisches Problem. Javascript ist ja im Gegensatz zu PHP ziemlich dürftig in Sachen Stringfunktionen ausgestattet. Zum Vergleichen, ob ein String gleich, größer oder kleiner als ein Anderer ist, habe ich bei Javascript nur die 0815 Operatoren < , > , == zur verfügung.
Ich lade nun ungefähr 3000 Namen aus einer MySQL Datenbank und packe diese in ein HTML Selectfeld (Dropdownbox). Man kann nun in dieser Dropdownbox mittels Javascript nach beliebigen Namen suchen.

Da das Suchen vom Anfang bis zum Ende (also jeden Datensatz durcharbeiten bis eine Übereinstimmung gefunden wird) zu lange dauert und die Suche auch noch bei 10000 Namen performant sein soll, kreise ich den gesuchten Namen erstmal grob ein und dannach suche ich in diesem Bereich mittels > , < , == nach einem Treffer.

Wenn ich aber z.B. nach mir selber suche (rené) habe ich auf dem letzten e ein ´ drauf. Laut MySQL juckt das ´ nicht und packt den Namen z.B. zwischen

rena
rené
renf

Javascript hingegen ist der Meinung, dass
rené > rennteil

Das Problem nun ist, dass in der ASCII-Tabelle das normale e mit der Dezimalzahl 101 und das é mit der Dezimalzahl 233 deklariert ist. So kommt es zu Stande, dass
rené > rennteil
ist. Denn in ASCII-Code ist das zweite n von rennteil < das é von rené.

FRAGE:Was kann man da machen, damit die Suche dennoch klappt?

Wäre nett, wenn darauf einer eine Antwort wüsste. Habe schon sämtliche Javascriptseiten durchgoogelt, aber nie etwas derartiges gefunden. Die kleckern alle mit Zahlenvergleichen rum. Das ist alles logisch. Stringvergleiche steht meistens nur wie Javascript es macht.

  1. Tag René.

    also ich habe da ein ziemlich komisches Problem.

    Hm, wie wäre es mit Regulären Ausdrücken statt der von dir verwendeten Vergleichsoperatoren. Auch indexOf() könnte helfen.

    Siechfred

    --
    Zum Testen freigegeben: Siechfreds kleines Weblog
    Wer Fehler findet, bitte an die angegebene E-Mail schicken. Danke.
  2. Hallo,

    Wenn ich aber z.B. nach mir selber suche (rené) habe ich auf dem letzten e ein ´ drauf. Laut MySQL juckt das ´

    Ja, MySQL hat eine entsprechend angepasste Sortierroutine. Normalerweise ist es nämlich genau so, wie Du beschrieben hast, nur dass es sich nicht um ASCII-Code handelt, sondern um charset=ISO-8859-1. ASCII-Code kennt nur Zeichen zwischen %00 und %7F (0-127).

    Bei der Suche ist es ähnlich, wie beim Sortieren.

    FRAGE:Was kann man da machen, damit die Suche dennoch klappt?

    Nutze ein Array http://de.selfhtml.org/javascript/objekte/array.htm und passe eine Array.sort(umlautSort)-Funktion http://de.selfhtml.org/javascript/objekte/array.htm#sort so an, dass die Funktion umlautSort(a, b) vor dem Vergleich der Werte a und b mit Hilfe von String.replace() http://de.selfhtml.org/javascript/objekte/string.htm#replace alle /ä/ durch "ae", alle /ö/ durch "oe", alle /ü/ durch "ue", alle /ß/ durch "ss", alle /é/ durch "ee", ... ersetzt.

    Nach dem Sortieren hast Du ein unter Beachtung der Umlaute sortiertes Array.

    Für Deine Suchmethode musst Du ähnlich vorgehen, also "René" suchen und im Weiteren wie "Renee" betrachten.

    viele Grüße

    Axel

  3. Hallo René,

    Javascript ist ja im Gegensatz zu PHP ziemlich dürftig in Sachen Stringfunktionen ausgestattet.

    Das Project jsPro auf Sourceforge, vorzugsweise die CVS-Version rüstet zahlreiche Funktionen für Javascript nach. Auch auf meiner Webseite im JavaScript-Bereich findest Du einiges, was von PHP inspiriert ist.

    Ich habe mal vor einiger Zeit eine PHP-Funktion geschrieben, um Arrays, die Sonderzeichen enthalten, nach den von dir gewünschten Maßstäben zu sortieren. Diese löst Dein Problem natürlich nicht direkt, bringt Dich aber vielleicht auf eine passende Idee.

    /////////////////////
    function spec_char_replace($orig_arr)
    {
      $search_arr  = array('À','Á','Â','Ã','Ä','Å','Æ','Ç','È','É','Ê','Ë',
                           'Ì','Í','Î','Ï','Ð','Ñ','Ò','Ó','Ô','Õ','Ö','Ø',
                           'Ù','Ú','Û','Ü','Ý','Þ','ß','à','á','â','ã','ä',
                           'å','æ','ç','è','é','ê','ë','ì','í','î','ï','ð',
                           'ñ','ò','ó','ô','õ','ö','ø','ù','ú','û','ü','ý',
                           'þ','ÿ');

    $replace_arr = array('A','A','A','A','A','A','A','C','E','E','E','E',
                           'I','I','I','I','E','N','O','O','O','O','O','O',
                           'U','U','U','U','Y','T','s','a','a','a','a','a',
                           'a','a','c','e','e','e','e','i','i','i','i','e',
                           'n','o','o','o','o','o','o','u','u','u','u','y',
                           't','y');

    $orig_arr = str_replace($search_arr, $replace_arr, $orig_arr);
      return $orig_arr;
    }

    function spec_char_natcasesort ($orig_arr)
    {
      $sort_arr = spec_char_replace($orig_arr);
      natcasesort($sort_arr);
      foreach($sort_arr as $key => $value)
      {
        $sort_arr[$key] = $orig_arr[$key];
      }
      return $sort_arr;
    }
    /////////////////////////

    Gruß,

    Dieter