Entwickler-Ecke
Grafische Benutzeroberflächen (VCL & FireMonkey) - 2 Listboxen miteinander vergleichen und Ergebnis ausgeben..
Terra23 - So 22.02.09 00:12
Titel: 2 Listboxen miteinander vergleichen und Ergebnis ausgeben..
Hi!
Ich weiß nicht, ob ich in diesem Unterforum richtig bin aber ich poste mal hier (verschieben kann man ja immer noch). Die Suche brachte keine für mich befriedigenden Ergebnisse.
Folgendes Problem:
Ich habe eine ListBox mit X Strings und eine weitere mit Y Strings.
Ich möchte die zweite ListBox nun durchsuchen lassen und zwar nach folgenden Gesichtspunkten:
Es soll geprüft werden, ob ein String aus der ersten ListBox in der zweiten vorhanden ist und falls ja, wie oft dies der Fall ist.
Ich habe schon mehrere Ansätze versucht (mit Repeat, mit For-Schleifen und dergleichen), aber ich kriege das einfach nicht hin.
Ich kann auch gern meinen Quellcode posten, allerdings kriege ich (immer, wenn ich das mache; wirklich IMMER) geschimpft, weil mein Code nicht lesbar genug ist und ich möge doch bitte mir den Thread durchlesen, wie man optisch ansprechenden Code schreibt etc.
Wenn mir jemand nen Hinweis geben könnte, wonach ich suchen soll, wäre mir schon ein wenig geholfen. Wenn jemand nen fertigen Code hat (normalerweise frage ich NIE nach fertigem Code, weil ich weiß, wie ihr dazu steht und weil ich lieber selbst schreibe), wäre das noch besser.
Zur Erläuterung (für alle, denen meine Romane zu unverständlich sind) nochmal das ganze dargestellt:
ListBox1:
Achim
Martin
Eva
Klaus
Nadine
ListBox2:
Achim
Nadine
Eva
Achim
Klaus
Martin
Klaus
Nadine
Martin
Martin
Achim
Eva
Eva
Wenn nun anhand der ersten ListBox die zweite durchsucht wird, müsste (in diesem Beispiel) folgendes Ergebnis rauskommen:
Achim: 3x
Nadine: 2x
Eva: 3x
Klaus: 2x
Martin: 3x
MfG
Terra
jaenicke - So 22.02.09 00:39
Wo ist denn das Problem? ;-)
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29:
| procedure TForm148.Button1Click(Sender: TObject);
procedure CountOccurrences(const List1, List2: TStrings; var Result: TStrings); var i, CurIndex: Integer; begin for i := 0 to List1.Count - 1 do Result.AddObject(List1[i], TObject(0)); for i := 0 to List2.Count - 1 do begin CurIndex := Result.IndexOf(List2[i]); if CurIndex >= 0 then Result.Objects[CurIndex] := TObject(Succ(Integer(Result.Objects[CurIndex]))); end; end;
var TempList: TStrings; i: Integer; begin TempList := TStringList.Create; try CountOccurrences(ListBox1.Items, ListBox2.Items, TempList); for i := 0 to TempList.Count - 1 do ShowMessage(TempList[i] + ': ' + IntToStr(Integer(TempList.Objects[i]))); finally TempList.Free; end; end; |
Und wenn du nur die Anzahlen haben willst, dann müssen die Strings auch nicht ins Ergebnis rein, dann reicht ein Integerarray:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26:
| procedure TForm148.Button2Click(Sender: TObject); type TIntArray = array of Integer;
procedure CountOccurrences(const List1, List2: TStrings; var Result: TIntArray); var i, CurIndex: Integer; begin for i := 0 to List2.Count - 1 do begin CurIndex := List1.IndexOf(List2[i]); if CurIndex >= 0 then Result[CurIndex] := Succ(Result[CurIndex]); end; end;
var TempList: TIntArray; i: Integer; begin SetLength(TempList, ListBox1.Items.Count); CountOccurrences(ListBox1.Items, ListBox2.Items, TempList); for i := Low(TempList) to High(TempList) do ShowMessage(ListBox1.Items[i] + ': ' + IntToStr(TempList[i])); SetLength(TempList, 0); end; |
Terra23 - So 22.02.09 16:03
Das Problem? ;) Ich habe Delphi nur ein Jahr in der Schule gehabt und habe mir das meiste mit Hilfe eures Forums oder durch ausprobieren beigebracht. Den Code, den du gepostet hast, werde ich mal testen, aber was für dich wie ein einfacher Code aussieht, ist für mich etwas, dass ich erstmal durchschauen muss. ;)
Erstmal danke für die Hilfe. Ich melde mich hier nochmal, ob es klappt oder nicht.
Terra
jaenicke - So 22.02.09 16:20
Was ich mache ist alle Einträge in der zweiten ListBox durchgehen und jeden in der ersten suchen. In der ersten Variante speichere ich die Anzahlen in einer TStringList inkl. der dazugehörigen Strings aus der ersten ListBox, in der zweiten Variante speichere ich nur die Anzahlen.
Bei einer TStringList mache ich mir zunutze, dass man ein Objekt zu jedem Eintrag speichern kann. Das gilt auch für
ListBox1.Items zum Beispiel. Jedenfalls ist sowas ein Pointer, und ein Pointer ist ein 4 Byte Integerwert. Also lege ich da keine Adresse eines Objekts (einen Pointer) ab, sondern benutze den Zahlenwert direkt zum Zählen. ;-)
Terra23 hat folgendes geschrieben : |
aber was für dich wie ein einfacher Code aussieht, ist für mich etwas, dass ich erstmal durchschauen muss. ;) |
Och, die erste Version ist durch den Trick gar nicht so besonders einfach, schon gar nicht, wenn man vielleicht Pointer gar nicht kennt. Das ist also normal, aber ich denke mal, das verstehst du schon. ;-)
Terra23 - So 22.02.09 16:41
Wenn ich deine erste Prozedur aufrufen will, was muss ich denn dann als Parameter für die Variable angeben?
Delete - So 22.02.09 16:56
Keine, Du musst nur in Form148 auf Button1 klicken.
jaenicke - So 22.02.09 17:07
Das ist ja nur ein Beispiel gewesen, meine Form heißt Form148 und der Button Button1, weil ich einfach nur ein neues Projekt erzeugt habe. Und die erste Zeile habe ich dabei gelassen, damit klar ist, dass es sich um einen ButtonClick handelt.
Wenn du deine beiden ListBoxen und nen Button hast, dann musst du den Quelltext nur da reinschreiben.
Und CountOccurrences rufe ich ja selbst auf, da siehst du ja den Aufruf.
Terra23 - So 22.02.09 17:19
Also bei deinem Code (jaenicke) treten bei mir folgende Probleme auf. Der erste Code funktioniert zwar super, allerdings kann ich den nicht so verändern, wie ich das gerne hätte.
Es werden zwar beide ListBoxen miteinander verglichen, aber ich möchte, dass dann noch folgendes passiert:
Wenn ein Name mehr als 1x auftaucht, soll der Name entsprechend der Überzahl in eine dritte ListBox übergeben werden, z.B.:
Martin ist 3x vorhanden, darf aber nur 1x vorhanden sein. Nun soll der String "Martin" 2x in die dritte ListBox geschrieben werden.
Das macht mir im Moment sehr zu schaffen.
Bei deinem zweiten Code beschwert sich Delphi darüber, dass TIntArray ein undefinierter Bezeichner wäre. Muss ich noch ne Unit ins Projekt einbinden? Falls ja, welche.
Gruß,
Terra
PS: Was ist bei dir List1 und was ist List2? Ist List1 das, was im Startpost bei mir ListBox1 ist?
jaenicke - So 22.02.09 17:24
Terra23 hat folgendes geschrieben : |
Es werden zwar beide ListBoxen miteinander verglichen, aber ich möchte, dass dann noch folgendes passiert:
[...] |
Naja, das Ergebnis durchgehen wie im ersten Beispiel und dann statt das per ShowMessage auszugeben schauen, ob die Anzahl größer 1 ist. Wenn ja, dann nimmst du die Anzahl minus 1 und hast die Anzahl für die dritte ListBox. Ansonsten (wenn die Anzahl genau 1 ist nämlich) musst du nichts tun.
Am einfachsten geht das mit einer for-Schleife von 0 bis Anzahl - 2. ;-)
Terra23 hat folgendes geschrieben : |
Bei deinem zweiten Code beschwert sich Delphi darüber, dass TIntArray ein undefinierter Bezeichner wäre. Muss ich noch ne Unit ins Projekt einbinden? Falls ja, welche. |
Ähm...
jaenicke hat folgendes geschrieben : |
Delphi-Quelltext 1: 2: 3: 4: 5:
| procedure TForm148.Button2Click(Sender: TObject); type TIntArray = array of Integer;
procedure CountOccurrences(const List1, List2: TStrings; var Result: TIntArray); | |
Terra23 hat folgendes geschrieben : |
PS: Was ist bei dir List1 und was ist List2? Ist List1 das, was im Startpost bei mir ListBox1 ist? |
Das sind die Parameter an die Prozedur, das können beliebige TStrings sein, in diesem Fall siehst du doch eigentlich was ich übergebe. Nämlich ListBox1.Items und ListBox2.Items.
Terra23 - So 22.02.09 17:58
Hab es hinbekommen. Vielen Dank für deine Hilfe und deine schier unendliche Geduld.
Terra
PS: Er hat sich nicht bei dem von dir orange markierten Teil beschwert, sondern hier:
procedure CountOccurrences(const List1, List2: TStrings; var Result: TIntArray);
jaenicke - So 22.02.09 18:28
Terra23 hat folgendes geschrieben : |
PS: Er hat sich nicht bei dem von dir orange markierten Teil beschwert, sondern hier:
procedure CountOccurrences(const List1, List2: TStrings; var Result: TIntArray); |
Ja, ich weiß, aber der markierte Teil ist die bei dir offenbar fehlende Deklaration. Wenn du die genauso dazu geschrieben hättest, dann würde TIntArray auch gefunden werden.
Terra23 - Sa 16.02.13 12:57
jaenicke hat folgendes geschrieben : |
Wo ist denn das Problem? ;-) Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29:
| procedure TForm148.Button1Click(Sender: TObject);
procedure CountOccurrences(const List1, List2: TStrings; var Result: TStrings); var i, CurIndex: Integer; begin for i := 0 to List1.Count - 1 do Result.AddObject(List1[i], TObject(0)); for i := 0 to List2.Count - 1 do begin CurIndex := Result.IndexOf(List2[i]); if CurIndex >= 0 then Result.Objects[CurIndex] := TObject(Succ(Integer(Result.Objects[CurIndex]))); end; end;
var TempList: TStrings; i: Integer; begin TempList := TStringList.Create; try CountOccurrences(ListBox1.Items, ListBox2.Items, TempList); for i := 0 to TempList.Count - 1 do ShowMessage(TempList[i] + ': ' + IntToStr(Integer(TempList.Objects[i]))); finally TempList.Free; end; end; | |
Sag mal, @
jaenicke:
Kannst du mir vielleicht auf die Sprünge helfen, wie ich bestimmte Zeilen dann einfärbe?
Den Code fürs Einfärben habe ich schon, ich weiß allerdings nicht, wo / wie der untergebracht werden muss und im Moment stehe ich total auf dem Schlauch.
Damit du weißt, worum es geht, ein Beispiel:
Ich habe eine Liste mit Namen, nennen wir sie "Liste_Keywords"...
Armin
Eva
Nils
Oliver
Ich habe eine weitere Liste mit Namen, nennen wir sie "Liste_Namen"...
Andy
Armin
Dave
Edgar
Eva
Jan
Nils
Oliver
Ich vergleiche nun die Listen mit deinem Code, was sehr gut funktioniert.
Nun möchte ich aber nicht nur angezeigt bekommen, wie oft ein Name in Liste_Namen steht sondern ich möchte in Liste_Namen alle Zeilen, die auch in Liste_Keywords sind, einfärben.
Dein Code funktioniert sehr gut, allerdings ist "TempList[i"] ja nicht gleichbedeutend mit "Liste_Namen[i]", da Liste_Namen ja mehr Items beinhaltet als TempList.
Magst du mir weiterhelfen?
Narses - So 17.02.13 00:57
Moin!
Bitte erstelle für jede deiner Fragen ein separates Topic, da die Diskussion mehrerer Fragen in einem Topic für gewöhnlich für Verwirrung und Durcheinander sorgt. :idea: Danke! ;)
cu
Narses
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!