ListBox, wenn gleiche Strings, dann überzählige löschen

Für Fragen von Einsteigern und Programmieranfängern...
Jakane
Beiträge: 53
Registriert: Mo 21. Feb 2011, 14:35

ListBox, wenn gleiche Strings, dann überzählige löschen

Beitrag von Jakane »

Guten Tag liebe Helfer :)

Ich häng gerade an einer ListBox fest.
In dieser ListBox stehen 2x Name1, 1x Name2, 16x Name3 und 7xName4.

Ich will natürlich nicht so oft Name3 in der Liste haben, sondern mir reicht (nachvollziehbarerweiser) 1x Name1, 1x Name2, 1x Name3 und 1x Name4.

Ich hab im Moment eine For-Schleife die sooft anfängt wie ListBox.Items.Count sagt
und dazu eine if-Anweisung die den aktuellen String mit dem kommenden vergleicht und gegebenfalls löschen soll

Aber ich hab da immer Programmfehler :(

Kann mir jemand zeigen wie es richtig geht?
Die Welt besteht aus Zahlen, also ist alles möglich.

Win XP

Socke
Lazarusforum e. V.
Beiträge: 3177
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: ListBox, wenn gleiche Strings, dann überzählige löschen

Beitrag von Socke »

Jakane hat geschrieben:Ich hab im Moment eine For-Schleife die sooft anfängt wie ListBox.Items.Count sagt
und dazu eine if-Anweisung die den aktuellen String mit dem kommenden vergleicht und gegebenfalls löschen soll

Aber ich hab da immer Programmfehler :(
Könnte der Fehler darin liegen, dass du beim Löschen die Anzahl der Strings in der ListBox änderst? Das bekommt die For-Schleife nicht mit und zählt trotzdem eins weiter, obwohl sie diesen Index nocheinmal überprüfen müsste (da da jetzt ein anderer Wert steht).
Daher: eine While-Schleife verwenden oder eine Zweite Liste erstellen (TStringList) und dort jede Zeichenkette einmal einfügen und am Ende diese Liste in die Listbox übernehmen.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

MAC
Beiträge: 770
Registriert: Sa 21. Feb 2009, 13:46
OS, Lazarus, FPC: Windows 7 (L 1.3 Built 43666 FPC 2.6.2)
CPU-Target: 32Bit

Re: ListBox, wenn gleiche Strings, dann überzählige löschen

Beitrag von MAC »

Du willst also alle doppelten Items löschen ?
Einfach :)
Nur muss man nen bisschen mitdenken :D :

Code: Alles auswählen

var
ok:boolean;
i,i2:integer;
begin
i := 0;
while i < Listbox1.Items,Count-1 do // -1 ist wichtig - da  "Count-1" das letzte ansprechbare item ist , sonnst gäbts fehler
begin
ok := true;
for i2 := 0 to i-1 do // alles bis auf das jetzige durchsuchen...
  begin
  if Listbox1.Items.Strings[i] = Listbox1.Items.Strings[i2] then
      begin
      ok := False;
      break; // schleife beenden
      end;
  end;
if ok then
   begin
   // Hura, das element taucht nur einmal auf.
   end
 else
   begin
   Listbox1.Items.Delet(i);
   dec(i); // sehr sehr wichtig !!!
   end; 
 inc(i); // sehr sehr wichtig !!! Nach jedem durchgang wird das i erhöht, klinkt logisch ist es auch - aber: wenn wir etwas gelöscht haben , dann lassen wir das i so ( -1 und danach +1 gleichen sich aus) , Da die nachfolgende Zeile eins aufrückt... Da wir i verändern brauchen wir eine while schleife und eine for schleife reicht nicht aus...  Edit: zu spät xD
 
 
  end;
 
 
 
 
end;
Jetzt kann man noch lowercase() benutzen , wenn dann würde der "Name3" und "name3" als gleich erkennen...

Code: Alles auswählen

Signatur := nil;

carli
Beiträge: 657
Registriert: Sa 9. Jan 2010, 17:32
OS, Lazarus, FPC: Linux 2.6.x, SVN-Lazarus, FPC 2.4.0-2
CPU-Target: 64Bit

Re: ListBox, wenn gleiche Strings, dann überzählige löschen

Beitrag von carli »

Kleiner Tipp:
Wenn du die Liste vorher sortierst, liegen gleiche Einträge immer nebeneinander und es lässt sich effizienter/einfacher ausfiltern.

creed steiger
Beiträge: 958
Registriert: Mo 11. Sep 2006, 22:56

Re: ListBox, wenn gleiche Strings, dann überzählige löschen

Beitrag von creed steiger »

Jakane hat geschrieben: Ich hab im Moment eine For-Schleife die sooft anfängt wie ListBox.Items.Count sagt
und dazu eine if-Anweisung die den aktuellen String mit dem kommenden vergleicht und gegebenfalls löschen soll

Aber ich hab da immer Programmfehler :(
Klarer Logikfehler.
Wenn deine Schleife über aller Elemente geht (z.B. 10 Einträge)
du aber in der Schleife Einträge löscht,läuft es am Ende in's leere weil
ja mittlerweile die gelöschten fehlen aber deine Schleife immer bis zu ursprüngliche Anzahl läuft.
Man könnte testweise ja mal versuchen von hinten anzufangen ;)

Benutzeravatar
theo
Beiträge: 10867
Registriert: Mo 11. Sep 2006, 19:01

Re: ListBox, wenn gleiche Strings, dann überzählige löschen

Beitrag von theo »

Am einfachsten geht folgendes:

Code: Alles auswählen

var Sl:TStringList;
begin
  Sl:=TStringList.Create;
  Sl.Sorted:=true;
  Sl.Duplicates:=dupIgnore;
  Sl.Assign(ListBox1.Items);
  Listbox1.Items.Assign(Sl);
  Sl.free;
end;

creed steiger
Beiträge: 958
Registriert: Mo 11. Sep 2006, 22:56

Re: ListBox, wenn gleiche Strings, dann überzählige löschen

Beitrag von creed steiger »

theo hat geschrieben:Am einfachsten geht folgendes:

Code: Alles auswählen

var Sl:TStringList;
begin
  Sl:=TStringList.Create;
  Sl.Sorted:=true;
  Sl.Duplicates:=dupIgnore;
  Sl.Assign(ListBox1.Items);
  Listbox1.Items.Assign(Sl);
  Sl.free;
end;
Laaaaaaaaangweilig ;)
(nicht bös gemeint)

Benutzeravatar
theo
Beiträge: 10867
Registriert: Mo 11. Sep 2006, 19:01

Re: ListBox, wenn gleiche Strings, dann überzählige löschen

Beitrag von theo »

creed steiger hat geschrieben: Laaaaaaaaangweilig ;)
Ja, schon. Alte Programmierer sind halt faule Säcke. ;-)

Lannes
Beiträge: 13
Registriert: Mo 16. Nov 2009, 22:14
OS, Lazarus, FPC: Windows XP, D3..D2010, Lazarus
CPU-Target: 32 Bit

Re: ListBox, wenn gleiche Strings, dann überzählige löschen

Beitrag von Lannes »

Hallo,

damit es nicht langweilig wird, auch etwas zum Nachdenken:

Code: Alles auswählen

with ListBox do
  for z := Pred(Items.Count) downto 1 do
    if Items.IndexOf(Items[z]) < z then
      Items.Delete(z);
(Nichts ist nicht Nichts) and (''<>nil)and(Pointer('')=nil)and(@('')<>nil)

Jakane
Beiträge: 53
Registriert: Mo 21. Feb 2011, 14:35

Re: ListBox, wenn gleiche Strings, dann überzählige löschen

Beitrag von Jakane »

Code: Alles auswählen

var Sl:TStringList;
begin
  Sl:=TStringList.Create;
  Sl.Sorted:=true;
  Sl.Duplicates:=dupIgnore;
  Sl.Assign(ListBox1.Items);
  Listbox1.Items.Assign(Sl);
  Sl.free;
end;
[/quote]

ich nehm die variante :D die versteh ich am besten, danke für die hilfe :)
Die Welt besteht aus Zahlen, also ist alles möglich.

Win XP

carli
Beiträge: 657
Registriert: Sa 9. Jan 2010, 17:32
OS, Lazarus, FPC: Linux 2.6.x, SVN-Lazarus, FPC 2.4.0-2
CPU-Target: 64Bit

Re: ListBox, wenn gleiche Strings, dann überzählige löschen

Beitrag von carli »

Jakane hat geschrieben:

Code: Alles auswählen

var Sl:TStringList;
begin
  Sl:=TStringList.Create;
  Sl.Sorted:=true;
  Sl.Duplicates:=dupIgnore;
  Sl.Assign(ListBox1.Items);
  Listbox1.Items.Assign(Sl);
  Sl.free;
end;
ich nehm die variante :D die versteh ich am besten, danke für die hilfe :)[/quote]

Gute Entscheidung.
Einmal korrekt implementiert, sollte man vorhandenen Code auch nutzen.

Jakane
Beiträge: 53
Registriert: Mo 21. Feb 2011, 14:35

Re: ListBox - Scrollbar-Pfeile

Beitrag von Jakane »

Hallo :lol: ja schon wieder ich :lol:

In meiner ListBox sind ja jetzt viele unterschiedliche Informationen die über ItemIndex noch unterschiedlichere Informationen anzeigen sollen. Klappt auch prima :D

Aber (weil ich ja ein fauler Mensch bin) will ich beim Index wechseln nicht immer Scroll-Bar klick und dann in die Liste klicken.

Ich würde gern das, wenn ich zB auf Item 5 bin und den Scroll-Bar eins hochklicke, das der dann automatisch auf Item 4 springt und ich das nicht extra neu markieren bzw anklicken muss.

Verrät mir jemand auf welche Funktion ich da zurück greifen muss? :roll:
Die Welt besteht aus Zahlen, also ist alles möglich.

Win XP

pluto
Lazarusforum e. V.
Beiträge: 7192
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: ListBox, wenn gleiche Strings, dann überzählige löschen

Beitrag von pluto »

Klarer Logikfehler.
Das stimmt nicht ganz. In der While Schleife wird direkt Items.Count-1 gesagt. D.H. theoretisch gesehen müsste in Items.Count-1 immer die Aktuelle Anzahl stehen. Meiner Meinung nach. D.H. es dürfte kein Fehler kommen.
Ich würde gern das, wenn ich zB auf Item 5 bin und den Scroll-Bar eins hochklicke, das der dann automatisch auf Item 4 springt und ich das nicht extra neu markieren bzw anklicken muss.
Das ist nicht so einfach möglich. Ob das überhaupt Möglich ist, bezweifle ich. Du müsstest dir selbst zwei Buttons anlegen, um den ItemIndex zu verändern.
du könntest dann den TopItem auf ItemIndex -1 oder +1 setzten.

Du könntest dir vielleicht von der Standard ListBox ableiten und dort die Entsprechende Methode Überschreiben. Also Praktisch eine eigene Komponenten erstellen, die von der Listbox alles Erbt und du nur das Verhalten etwas anpasst. Aber ob das geht, weiß ich nicht genau.

Die Methode müsste Irgendetwas mit Scroll im Namen haben *G*.
MFG
Michael Springwald

Lannes
Beiträge: 13
Registriert: Mo 16. Nov 2009, 22:14
OS, Lazarus, FPC: Windows XP, D3..D2010, Lazarus
CPU-Target: 32 Bit

Re: ListBox, wenn gleiche Strings, dann überzählige löschen

Beitrag von Lannes »

pluto hat geschrieben:
Klarer Logikfehler.
Das stimmt nicht ganz. In der While Schleife wird direkt Items.Count-1 gesagt. D.H. theoretisch gesehen müsste in Items.Count-1 immer die Aktuelle Anzahl stehen. Meiner Meinung nach. D.H. es dürfte kein Fehler kommen.
die Aussage "Klarer Logikfehler" bezog sich auf ein Löschen per For-Schleife, und dann ist es ein Logikfehler, denn die Ende-Bedingung Items.Count-1 wird, im Gegrensatz zur while-Schleife, nur ein mal zu Beginn der For-Schleife überprüft und nicht bei jedem Loop.
(Nichts ist nicht Nichts) and (''<>nil)and(Pointer('')=nil)and(@('')<>nil)

pluto
Lazarusforum e. V.
Beiträge: 7192
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: ListBox, wenn gleiche Strings, dann überzählige löschen

Beitrag von pluto »

die Aussage "Klarer Logikfehler" bezog sich auf ein Löschen per For-Schleife, und dann ist es ein Logikfehler, denn die Ende-Bedingung Items.Count-1 wird, im Gegrensatz zur while-Schleife, nur ein mal zu Beginn der For-Schleife überprüft und nicht bei jedem Loop.
Das ist mir neu. Ich dachte die wir bei jedem Durchgang geprüft... Gut zu wissen.
MFG
Michael Springwald

Antworten