FindItem suchen nach 2ter spalte in CListCtrl (Hashkey)
-
Hängt also ab, wie Du hinzufügst. Wenn Du immer nur anhängst kanst Du eine Map auf den Zeilenindex bauen.
Ja das wäre am einfachsten gewesen. Aber da man die Liste auch sortieren kann, wäre es spätestens dann zu Ende.
Ansonsten bau Dir eine virtuelles List View.
Ok. Was ist das? Das existiert dann parallel zu meinem ListControl? Muss ich mir mal genau durchlesen.
Mein Vorschlag mit dem Hashkey hast du bisher total ignoriert. Mit Absicht? Keine gute Lösung?
-
Ja das habe ich ignoriert weil es nichts bringt. Denk doch mal nach.
Du willst eine bestimmte Zele finden... OK dann kannst musst Du die Liste von Oben nach unten durchlaufen.
Wnen Du das vermeiden willst baruauchst Du eine map von Daten -> Zeile...
Und? Die Zele ändert sich aber evtl. (Zeile wird gelöscht, sortierung ändert sich).Wenn Du damit leben kannst die Zeile nach einer bestimmten Info zu durchsuchen. Also von 0..n dann kann Dir das egal sein.
Einzig eine virtuelle iste in der Du selber die daten verwaltest und entscheidest was angezeigt wird, ist natürlich von dieser Suche befreit...
Hier stimmt Anzeigeimmer mit Deiner Info im Speicher überein.
-
Ja das habe ich ignoriert weil es nichts bringt. Denk doch mal nach.
Nun ja. Das bringt meiner Meinung schon was. Denn ich muss nun nur noch nach der ersten Spalte durchsuchen. Ich kann FindItem nutzen - klar dass dieser die Liste auch durchläuft - aber nur die erste Spalte.
Sozusagen habe ich dann in meiner Tabelle dann auch wie im Taskmanager eine PID.
Sicher wäre ein virtuelles Listview für die Suche noch besser. Aber baut man für jedes Listcontroll das man durchsuchen will ein virtuelles Listview?
Mein Problem mit der nicht eindeutigen Spalte hätte ich durch die zusätzliche Spalte mit dem Haskey gelöst.
Oder habe ich nicht recht?
-
y-vonne schrieb:
Das Problem ist dass ich alle paar Millisekunden einen Wert im ListControl update.
So schnell kannst du gucken?
Im Ernst: Wenn du nicht gerade einen automatisch ausgewerteten Hochgeschwindigkeits-Video-Stream erzeugst, reichen auch ein paar Aktualisierungen pro Sekunde. Ein menschlicher Betrachter kann sowieso nicht mehr erfassen.
Dein grafisches Steuerelement muss nicht auf jede Änderung sofort reagieren, das kann es auch gar nicht, und es bringt auch nichts. Aktualisiere einfach in regelmäßigen Abständen, vielleicht so alle 200 ms.
Vereinfacht wird das ganze, wenn du dein grafisches Steuerelement nicht als Datenspeicher benutzt. Die darzustellenden Daten müssen in deinem Programm vorliegen, in einer geeigneten Datenstruktur, die du schnell ändern kannst. Das Listcontrol kümmert sich nur um die Darstellung.
-
Mit alle paar Milisekunden meinte ich das so zwischen 250 ms und 1000 ms. Ist aber auch egal das war hier nicht die Anforderung.
Vereinfacht wird das ganze, wenn du dein grafisches Steuerelement nicht als Datenspeicher benutzt. Die darzustellenden Daten müssen in deinem Programm vorliegen, in einer geeigneten Datenstruktur, die du schnell ändern kannst. Das Listcontrol kümmert sich nur um die Darstellung.
Ja das habe ich ja ausführlich geschrieben, dass ich das habe. Bitte ganzen Tread lesen.
Wenn Martin mir noch meine letzte Frage beantworten würde wäre ich glücklich
-
y-vonne schrieb:
Wenn Martin mir noch meine letzte Frage beantworten würde wäre ich glücklich
Ich denke, Martin versucht dir zu erklären, dass es nichts bringt, dein Listcontrol zu durchsuchen, weil das unnötig Zeit verbraucht.
Mach dein Listcontrol virtuell, dann hält es selbst die Daten nicht mehr vor, und fragt nur noch nach den Daten, die es für die Anzeige braucht.
-
y-vonne schrieb:
Nun ja. Das bringt meiner Meinung schon was. Denn ich muss nun nur noch nach der ersten Spalte durchsuchen. Ich kann FindItem nutzen - klar dass dieser die Liste auch durchläuft - aber nur die erste Spalte.
Was bringt dasbitte?
Das sucht sequentiell. Immer noch.
Das bringt also gar nichts.O(n) für jedes Upate!
Sozusagen habe ich dann in meiner Tabelle dann auch wie im Taskmanager eine PID.
Und? Wie aktualisierst Du den Bezug, also die Zeilennummer.
Da wird irendwo eine Zeile eingefügt oder gar umsortiert...
Was ist mit Deiner Tabelle. Auf was bitte verweist die?Sicher wäre ein virtuelles Listview für die Suche noch besser. Aber baut man für jedes Listcontroll das man durchsuchen will ein virtuelles Listview?
Das hängt von den Anforderungen ab.
Wenn ich meine Daten komplett selber verwalte, dan nehme ich nie ein normales ListView. Da muß ich ja alle daten "kopieren"...Mein Problem mit der nicht eindeutigen Spalte hätte ich durch die zusätzliche Spalte mit dem Haskey gelöst.
Oder habe ich nicht recht?Nee. Hast Du nicht. Weil Du nicht das Problem der "Eindeutigkeit" hast. Dazu kannst Du das ItemData in ListView benutzen. Das ist viel enfacher.
Dein Problem bei einer großen Liste ist das lokalisieren des Items...
Ich sage nur nochmal O(n)
-
Ich denke, Martin versucht dir zu erklären, dass es nichts bringt, dein Listcontrol zu durchsuchen, weil das unnötig Zeit verbraucht.
Ist ja ok. Ich weiß dass es Zeit braucht. Wollte aber was anderes wissen!!
Ein virtuelles Listcontrol wird verwendet für viele Daten. Ich habe maximal 40 Einträge in der Liste. Ich denke die zu durchsuchen benötigt nun nicht sehr viel Zeit.
Und hier wäre es praktisch wenn man nur in einer Spalte suchen müßte. Und darum die Idee mit dem Hashkey.
Vieleicht hier nochmals direkt gefragt: Wie kann ich einen Hashkey aus einem String erzeugen.
-
Hallo Martin habe deinen letzten Beitrag zu spät gesehen.
Also
Was bringt das bitte?
Das sucht sequentiell. Immer noch.Ja weiß ich. Aber das ist ja eigentlich nicht mein Problem bei nur maximal 40 Einträgen:
O(n) für jedes Upate!
? Versteh nicht was O(n) bedeutet. Sorry. Ist das eine Null oder ein o'h?
Weil Du nicht das Problem der "Eindeutigkeit" hast.
Dazu kannst Du das ItemData in ListView benutzen.Wo habe ich das? Ich verwende CListCtrl::InsertItem. Wo habe ich da ein ItemData?
-
y-vonne schrieb:
Wollte aber was anderes wissen!!
Deine Sturheit ist erschreckend. Ein letzter Versuch: Dein Lösungansatz ist Blödsinn! Durchsuch nicht dein Listcontrol, sondern organisier deine Datenstruktur so, dass du weißt, welche Zeile sich geändert hat.
y-vonne schrieb:
Vieleicht hier nochmals direkt gefragt: Wie kann ich einen Hashkey aus einem String erzeugen.
Mit einer Hashfunktion.
-
Deine Sturheit ist erschreckend.
Danke aber manchmal kommt man sonst im Leben nicht weiter.
Momentan verwende ich ein Listcontrol von "The Code Project".
Das Ding ermöglicht es einem zu sortieren, gruppieren, Spalten auszublenden usw. All das was ich brauche bis auf die Suchfunktion halt.
Wenn ich nun eine Virtuelles ListControl verwende ist das auch alles dahin und ich muss dass auch alles neu machen. Und das eigentlich nur wegen einem kleinen Dialog der nur ein paar Informationen anzeigen soll. Und ich hier in meinem Projekt nicht viel Zeit dafür eingeplant bekommen habe.
-
y-vonne schrieb:
Momentan verwende ich ein Listcontrol von "The Code Project".
Die Info wäre gleich zu Anfang hilfreich gewesen.
Schau dir mal die Überladungen von CListCtrl::InsertItem an. Es gibt da eine mit einem lParam-Parameter (der steckt auch in der LVITEM-Struktur), damit kannst du jedem Eintrag einen 32-Bit-Wert zuordnen. Leg da einen Schlüssel ab (keinen Hash), über den du eindeutig erkennen kannst, um welche Zeile es sich handelt, das dürfte das einfachste sein.
-
Die Info wäre gleich zu Anfang hilfreich gewesen.
Sorry wußte ich nicht. Dachte da das Control auch nur von CListControl ableitet und bei der Suche keine Erweiterung vorgenommen hat wäre das in diesem Kontext nicht wichtig.
Dass es ein virtuelles Listcontroll gibt und das dann halt mit dem CListCtrlEx nicht zusammenpasst wußte ich ja zu dem Zeitpunkt noch nicht.
Leg da einen Schlüssel ab (keinen Hash), über den du eindeutig erkennen kannst, um welche Zeile es sich handelt, das dürfte das einfachste sein.
Ok. Dachte ein Hash wäre ein eindeutiger Schlüssel? Was gibt es sonst noch für möglichkeiten um einen eindeutigen Schlüssel zu erzeugen?
-
y-vonne schrieb:
Ok. Dachte ein Hash wäre ein eindeutiger Schlüssel?
Nein, kann gar nicht. Es gibt ja viel mehr mögliche Strings als mögliche Hash-Werte.
y-vonne schrieb:
Was gibt es sonst noch für möglichkeiten um einen eindeutigen Schlüssel zu erzeugen?
Das kommt auf deine Daten an. Vielleicht ein einfacher Index auf deine interne Datenstruktur?
-
Nein, kann gar nicht. Es gibt ja viel mehr mögliche Strings als mögliche Hash-Werte.
Aha
Das kommt auf deine Daten an. Vielleicht ein einfacher Index auf deine interne Datenstruktur?
Meine Daten sind einfach. 2 Strings und eine Zeit die ich aktualisieren muss.
Aber wie ich daraus einen Index erzeugen soll? KA. Sorry
-
y-vonne schrieb:
Meine Daten sind einfach. 2 Strings und eine Zeit die ich aktualisieren muss.
Diese Daten liegen doch irgendwo im Speicher, in einer Datenstruktur. Array, Vector oder so etwas.
Dann kannst du die Position in dieser Struktur im Listcontrol ablegen.
Wenn sich dann beispielsweise der 3. Eintrag in deiner Datenstruktur ändert, suchst du im Listcontrol die Zeile mit dem lParam-Wert 3.
-
Hallo
Diese Daten liegen doch irgendwo im Speicher, in einer Datenstruktur. Array, Vector oder so etwas.
Dann kannst du die Position in dieser Struktur im Listcontrol ablegen.
Jo in einer map. Key ist ein pair aus zwei Strings. Hat eine Map auch Positionen?
Wenn sich dann beispielsweise der 3. Eintrag in deiner Datenstruktur ändert, suchst du im Listcontrol die Zeile mit dem lParam-Wert 3.
Dann habe ich aber immer noch das Problem auf das Martin hingedeutet hat.
Und zwar suche ich dann immer noch mit FindItem. Und gehe die Liste durch. Schneller ist es dann auch nicht. Und das Problem wenn während desen sortiert wird besteht auch noch. Darauf hat mich Martin ja hingewiesen. Dass ich nicht das Problem der Eindeutigkeit habe.
-
y-vonne schrieb:
Jo in einer map. Key ist ein pair aus zwei Strings. Hat eine Map auch Positionen?
Nicht direkt. Du könntest die Daten in einem Vector ablegen, und in der Map nur die Position im Vector.
y-vonne schrieb:
Dann habe ich aber immer noch das Problem auf das Martin hingedeutet hat.
Und zwar suche ich dann immer noch mit FindItem.
Nein, du kannst mit CListCtrl::GetItemData den lParam-Wert direkt auslesen.
y-vonne schrieb:
Schneller ist es dann auch nicht.
Doch, weil du nicht mit Strings hantieren musst.
y-vonne schrieb:
Und das Problem wenn während desen sortiert wird besteht auch noch. Darauf hat mich Martin ja hingewiesen.
Das Problem, das er meinte, besteht dann, wenn du das Listcontrol nicht durchsuchst, sondern dir merkst, wo welcher Datensatz steht. Wenn du suchst, hast du das nicht.
y-vonne schrieb:
Dass ich nicht das Problem der Eindeutigkeit habe.
Das Eindeutigkeitsproblem ergibt sich aus deinem Hash-Ansatz, weil ein Hash eben nicht eindeutig ist.
-
Jo in einer map. Key ist ein pair aus zwei Strings. Hat eine Map auch Positionen? Nicht direkt. Du könntest die Daten in einem Vector ablegen, und in der Map nur die Position im Vector.
Puh, noch mehr Speicherverwaltung. Eine andere Möglichkeit gibts nicht. z.B. einen Zeiger auf den key der Map anstatt der position.
Das Problem, das er meinte, besteht dann, wenn du das Listcontrol nicht durchsuchst, sondern dir merkst, wo welcher Datensatz steht. Wenn du suchst, hast du das nicht.
Nein das wollte ich ja nie machen. Habe ja gesagt ich will so was wie eine PID erzeugen und dann immer nach dieser suchen. Immer wenn aktualisiert wird. Und dort hätte ich dann auch nicht mit Strings rumhantiert.
Ich habe das eher so verstanden. Denn wenn ich eine weitere Spalte eingefügt hätte dort einen PID eingefügt hätte (fälschlicherweise war ich der Meinung das sei das selbe wie ein Hashwert) hätte ich auch mit GetItemCount suchen können.
Ließ nochmals den Beitrag von Martin dort wo er auf "O(n)" hingewiesen hat, (was ich im übrigen immer noch nicht verstehe):
Dort sagt er:
Dein Problem bei einer großen Liste ist das lokalisieren des Items...
-
y-vonne schrieb:
Eine andere Möglichkeit gibts nicht. z.B. einen Zeiger auf den key der Map anstatt der position.
Soll das eine Frage oder eine Aussage sein?
y-vonne schrieb:
Und dort hätte ich dann auch nicht mit Strings rumhantiert.
Wenn du diesen erzeugten Wert, wie auch immer du ihn nennst, in einer zusätzlichen Spalte ablegst, hantierst du mit Strings, denn das Listcontrol speichert diese Werte als Strings. Darum ja das lParam, das wird direkt als Zahlenwert abgelegt.
y-vonne schrieb:
Ließ nochmals den Beitrag von Martin dort wo er auf "O(n)" hingewiesen hat
Brauch ich nicht, ich hab's ja verstanden. Worauf willst du hinaus?