Jense: Autocomplete und Bitoperatoren - Experte gesucht

Guten Abend allerseits,
heute mal eine Frage an die wahren Insider - folgende Aufgabenstellung:
Grundsätzlich geht es erstmal um eine Autocomplete-Version. Soll wie immer kurz und kanckig sein. Habe im netz auch was nettes gefunden:

function binSuche(elem)
{
   var links = -1;
       var rechts = this.length;
       var mitte;

while(rechts - links > 1)
   {
      mitte = (links + rechts) >>> 1;
      if(this[mitte] < elem)
         links = mitte;
      else
         rechts = mitte;
   }

if(this[rechts] != elem)
      return -(rechts + 1);

return rechts;
}

alert([["a"],["b"],["d"]].binSuche("c"));  // Testausgabe

Tolle Sache! Gibt bei nicht vorhandenem Element die Stelle an der es eingefügt werden muss als negative Zahl an, wobei bei 1 angefangen wird zu zählen. Ist das Element dagegen in der Menge vorhanden, dann wird bei Null angefangen zu zählen und die positive Zahl gibt die entsprechende Stelle im Feld an. (Nur der vollständigkeithalber: das Feld muss bereits vollständig vorsortiert sein, denn es geht hier nur um das Einsortieren...) Soweit sogut, funktioniert super, und ich vermute ohne das ich es getestet habe, dass es auch relativ schnell geht, da Bit-Operatoren benutzt werden. Jetzt kommen wir zu meinem Problem: Ich habe im Prinzip keine Ahnung wie und warum die Prozedur funktioniert was mich in diesem Fall auch nur deshalb stört da meine Anforderungen etwas abweichen, ich aber das Ding nicht anpassen kann. Wie gesagt keine Ahnung welche Einsen und Nullen sich da wo, wie und warum verschieben. Bin ja selber eine Null...
Ich habe ein zweidimensionales Feld. Es gibt immer Paare von ID's und dazugehörigen Bezeichnern, also z.B.: [[0,"a"],[1,"b"],...]
Also nichts ungewöhnliches aber eben anders als hier ursprünglich vorgesehen. Sortiert werden soll übrigens nach dem Bezeichner (wie gesagt: autocomplete), aber ich brauch eben auch die Nummer.
Jetzt bin ich gespannt wer von euch sich als echter Spezi outet und mir das Ding hinbiegt. Tausend Dank schonmal vorab!!!

Jense

  1. Grundsätzlich geht es erstmal um eine Autocomplete-Version. Soll wie immer kurz und kanckig sein. Habe im netz auch was nettes gefunden:

    Was ist Autocomplete?

    function binSuche(elem)
    {
       var links = -1;
           var rechts = this.length;

    Was ist this hier?
    Du hast nirgends ein Objekt, dann ist this == window.

    alert([["a"],["b"],["d"]].binSuche("c"));  // Testausgabe

    Fehler: [["a"], ["b"], ["d"]].binSuche is not a function
    Quelldatei: test.html
    Zeile: 54

    Vielleicht sagst du uns noch um was es konkret geht?

    Struppi.

    1. Hi,

      ich bin gerade auf dem Sprung, kann mich um das eigentliche Problem gerade mal nicht kümmern, aber:

      alert([["a"],["b"],["d"]].binSuche("c"));  // Testausgabe
      Fehler: [["a"], ["b"], ["d"]].binSuche is not a function

      Array.prototype.binSuche = binSuche;

      Danach sollte es gehen.

      Cheatah

      --
      X-Self-Code: sh:( fo:} ch:~ rl:° br:> n4:& ie:% mo:) va:) de:] zu:) fl:{ ss:) ls:~ js:|
      X-Self-Code-Url: http://emmanuel.dammerer.at/selfcode.html
      X-Will-Answer-Email: No
      X-Please-Search-Archive-First: Absolutely Yes
      1. ich bin gerade auf dem Sprung, kann mich um das eigentliche Problem gerade mal nicht kümmern, aber:

        Ich auch ;-)

        alert([["a"],["b"],["d"]].binSuche("c"));  // Testausgabe
        Fehler: [["a"], ["b"], ["d"]].binSuche is not a function

        Array.prototype.binSuche = binSuche;

        Danach sollte es gehen.

        Mir ist das klar, aber warum kriegen wir nur ein kastriertes Beispiel?
        Und warum schreib man nicht gleich:

        Array.prototype.binSuche = fucntion() {  
        }  
        
        

        Wie auch immer, wenn es nur um die Bitoperatoren geht, hier im Forum müßte ein aktiver Thread sein, in dem darauf hingewiesen wurde, dass diese unter JS nicht schneller sind als normale Rechneoperationen - hab ich aber noch nie getestet.

        Struppi.

        1. Hi,

          Wie auch immer, wenn es nur um die Bitoperatoren geht, hier im Forum müßte ein aktiver Thread sein, in dem darauf hingewiesen wurde, dass diese unter JS nicht schneller sind als normale Rechneoperationen.

          Hier ist er.

          mfG,
          steckl

        2. Hallo nochmal,

          alert([["a"],["b"],["d"]].binSuche("c"));  // Testausgabe
          Fehler: [["a"], ["b"], ["d"]].binSuche is not a function

          Array.prototype.binSuche = binSuche;

          Danach sollte es gehen.

          Ein Experte!!! OK ich habe das Array.prototype. weggenommen. Nicht zum Spass, sondern weil mein Skript plötzlich an einer ganz anderen Stelle nicht mehr lief als ich die Version mit Array.prototype. eingefügt habe (ohne das ich die Funktion schon benutzt hätte!?!). Da ich wie gesagt von dieser Programmierebene keinen blassen schimmer habe, bin ich nach der trial and error methode vorgegangen. Bei mir funktioniert es so auch. Keine Fehler, auch der Rest des Scriptes läuft wie zuvor reibungslos). Werde jetzt aber nochmal ein bisschen rumprobieren...

          Mir ist das klar, aber warum kriegen wir nur ein kastriertes Beispiel?

          Das Beispiel ist nicht kastriert sondern entspricht genau meinen Vorgaben und Ansprüchen irgendwelches drumherum würde mein Anliegen nur (noch?) unverständlicher machen

          Und warum schreib man nicht gleich:

          Array.prototype.binSuche = fucntion() {

          }

          
          >   
          > Wie auch immer, wenn es nur um die Bitoperatoren geht, hier im Forum müßte ein aktiver Thread sein, in dem darauf hingewiesen wurde, dass diese unter JS nicht schneller sind als normale Rechneoperationen - hab ich aber noch nie getestet.  
          >   
          
          Wie gesagt ich auch nicht...es ist aber auch einfach eine elegante Methode - da wenig Code, deshalb würde ich die Funktion gerne nutzen - abgeändert natürlich.  
          Vielleicht könnt Ihr euch die Tage darüber nochmal auslassen, denn ich glaube Ihr habt das grundsätzlich drauf...  
            
          Gruss Jense
          
    2. Nabend Struppi,

      Was ist Autocomplete?

      'AutoVervollständigen' heisst die Option z.B. im IE - dass Du danach fragst wundert mich!
      Es ist dieselbe Funktion die man von 'zu Hause' kennt, wobei ja eigentlich nicht automatisch vervollständigt wird (gibt es ja auch) sondern die Liste mit bereits mal eingegebenen oder vorhandenen Daten nur entsprechend mitläuft, bzw. eingegrenzt wird.

      function binSuche(elem)
      {
         var links = -1;
             var rechts = this.length;

      Was ist this hier?

      Das war doch meine Frage :)

      Du hast nirgends ein Objekt, dann ist this == window.

      Wo steht das denn?

      alert([["a"],["b"],["d"]].binSuche("c"));  // Testausgabe

      Fehler: [["a"], ["b"], ["d"]].binSuche is not a function
      Quelldatei: test.html
      Zeile: 54

      Also bei mir funktioniert es tadellos...

      Vielleicht sagst du uns noch um was es konkret geht?

      Konkret nochmal anders formuliert: Ich habe ein zweidimensionales Feld wie beschrieben mit Paaren von ID und Bezeichnern. Jetzt brauche ich eine Funktion die mir die die Stelle des Arrays (indem die Einträge alphabetisch nach den Bezeichnern vorsortiert sind) angibt wo eine beliebige Eingabe einsortiert werden müsste, sofern diese noch nicht im array vorhanden ist, bzw an welcher Stelle des arrays die Eingabe schon existiert. Wie gesagt sortiert und eingefügt wird alphabetisch nach den Bezeichnern. Die ID's müssten halt mitsortiert werden. Ich hoffe es ist jetzt etwas klarer geworden. Wenn nicht... bitte fragen.

      Gruss Jense

      1. Was ist Autocomplete?

        'AutoVervollständigen' heisst die Option z.B. im IE - dass Du danach fragst wundert mich!

        Ich weiß was eine Autocomplete Funktion ist, aber was zeigst du uns da?

        function binSuche(elem)
        {
           var links = -1;
               var rechts = this.length;

        Was ist this hier?
        Das war doch meine Frage :)

        Ok, so wie du es geschrieben hast ist this = window, vermutlich nicht das was du willst.

        Du hast nirgends ein Objekt, dann ist this == window.
        Wo steht das denn?

        Das ist so, this ist immer der Kontext  in dem eine Funktion aufgerufen wird und da hier kein Objekt existiert ist this gleich window

        alert([["a"],["b"],["d"]].binSuche("c"));  // Testausgabe

        Fehler: [["a"], ["b"], ["d"]].binSuche is not a function
        Quelldatei: test.html
        Zeile: 54

        Also bei mir funktioniert es tadellos...

        Dann zeigst du uns nicht alles.

        Vielleicht sagst du uns noch um was es konkret geht?

        Konkret nochmal anders formuliert: Ich habe ein zweidimensionales Feld wie beschrieben mit Paaren von ID und Bezeichnern. Jetzt brauche ich eine Funktion die mir die die Stelle des Arrays (indem die Einträge alphabetisch nach den Bezeichnern vorsortiert sind) angibt wo eine beliebige Eingabe einsortiert werden müsste, sofern diese noch nicht im array vorhanden ist, bzw an welcher Stelle des arrays die Eingabe schon existiert. Wie gesagt sortiert und eingefügt wird alphabetisch nach den Bezeichnern. Die ID's müssten halt mitsortiert werden. Ich hoffe es ist jetzt etwas klarer geworden. Wenn nicht... bitte fragen.

        Das klingt so trivial, dass ich nicht vermute das ich verstanden habe worum es geht.

        for(var i = 0; i < array.length; i++ ){  
        if( array[i] > eintrag ) alert('hier:' + i);  
        }  
        
        

        Struppi.

        1. alert([["a"],["b"],["d"]].binSuche("c"));  // Testausgabe

          Fehler: [["a"], ["b"], ["d"]].binSuche is not a function
          Quelldatei: test.html
          Zeile: 54

          Also bei mir funktioniert es tadellos...

          Dann zeigst du uns nicht alles.

          doch, klar die script tags oder wie die heissen hab ich weggelasen - die Frage läuft ja unter js....

          Das klingt so trivial, dass ich nicht vermute das ich verstanden habe worum es geht.

          trivial - kann man so sehen. Es ist halt grundsätzlich ein Einfügeproblem in eine bereits sortierte Menge

          for(var i = 0; i < array.length; i++ ){

          if( array[i] > eintrag ) alert('hier:' + i);
          }

          
          >   
          
          Das ist natürlich auch eine Lösung - also Du weisst um was es geht!  
          Ich möchte allerdings die sogenannte 'Binäre Suche' in einer Funktion umgesetzt haben, da diese bei grösseren Feldern klare Performancevorteile hat.  
            
          Jense  
          
          
      2. Hallo,

        Sortieren kannst du so einen Array mit einer eigenen Vergleichsfunktion:

        arr.sort(function (a, b) {
          if (a[1] < b[1])
            return -1;
          if (a[1] > b[1])
            return 1;
          return 0;
        });

        Sinniger wäre es, dass die Arrayelemente Objekte sind:
        [ { id : "...", bezeichner : "..." }, ... ]

        Dann kannst du statt a[0] a.id und statt a[1] a.bezeichner schreiben. Dementsprechend:

        arr.sort(function (a, b) {
          if (a.bezeichner < b.bezeichner)
            return -1;
          if (a.bezeichner > b.bezeichner)
            return 1;
          return 0;
        });

        Wenn du jetzt eine Binäre Suche über diesen Array mit Objects machen willst, schreibst du die Funktion entsprechend um. Der Zugriff auf das maßgebende Element verläuft nicht über this[index], sondern über this[index].bezeichner. Ist eigentlich simpel.

        http://molily.de/temp/binaere-suche.html

        Aber was hat das Ganze konkret mit AutoComplete zu tun? AutoComplete verstehe ich so, dass man einen Teil eines Begriffes eingibt und automatisch alle zuvor eingegebenen Begriffe angezeigt werden, die mit diesem Teil beginnen.
        Was hast du eigentlich genau vor? Mir kommt dieses Konstrukt dermaßen umständlich vor, dass es sicher eine einfachere Lösung gibt. Was genau willst du? Willst du in den Array etwas einsortieren (warum?) oder einfach schauen, ob ein Wert drinsteht?
        Willst du die ID zu einem Bezeichner extrahieren? Dann kannst du auch einfach ein Object nehmen, in der die Abbildung von Bezeichner auf ID gespeichert ist und du kannst dir die ganze Sortierung und Binäre Suche sparen.

        Mathias