![]() |
Zwei Listen filtern Denkproblem
Ich komme gerade nicht weiter weil ich einen Knoten im Kopf habe.
ich habe zwei Listen. Eine enthält Städtenamen und die andere enthält jede statt mit jeder Stadt mit Komma getrennt. Zitat:
Zitat:
|
AW: Zwei Listen filtern Denkproblem
Du musst deine Problem in Teilprobleme zerlegen.
1. Aus einem String mit komma-getrennten Werten ein string-Array erstellen 2. Entfernen von Einträgen aus einem Array, wenn diese nicht in einem anderen Array enthalten sind 3. Aus einem String-Array wieder einen String mit den komma-getrennten Einträgen erstellen Wo hast du Probleme? |
AW: Zwei Listen filtern Denkproblem
Zitat:
Zitat:
Zitat:
Arrays brauche ich nicht. Habe wie gesagt schon alles in Klassen und die erste Städteliste ist eine StringList. |
AW: Zwei Listen filtern Denkproblem
EDIT: Bitte ignorieren, habe einen Denkfehler drin.
|
AW: Zwei Listen filtern Denkproblem
Zitat:
Hier mal eine abstrakte Darstellung deines Problems aus Punkt 2: Entferne alle Einträge aus Menge A die nicht in der Menge B enthalten sind. So einfach, so schlicht, ... so trivial |
AW: Zwei Listen filtern Denkproblem
Ich möchte Städte aus Liste 2 löschen die nicht in Liste 1 sind.
Delphi-Quellcode:
Bei diesem Beispiel sollen alle Einträge mit napoli aus Staedte2 entfernt werden.
Staedte1 := TStringList.Create;
Staedte2 := TStringList.Create; try // Liste 1 Staedte1.Add('berlin'); Staedte1.Add('dusseldorf'); Staedte1.Add('koln'); Staedte1.Add('nurnberg'); // Liste 2 Staedte2.Add('berlin,berlin'); Staedte2.Add('berlin,dusseldorf'); Staedte2.Add('berlin,koln'); Staedte2.Add('berlin,napoli'); Staedte2.Add('berlin,nurnberg'); Staedte2.Add('dusseldorf,berlin'); Staedte2.Add('dusseldorf,dusseldorf'); Staedte2.Add('dusseldorf,koln'); Staedte2.Add('dusseldorf,napoli'); Staedte2.Add('dusseldorf,nurnberg'); Staedte2.Add('koln,berlin'); Staedte2.Add('koln,dusseldorf'); Staedte2.Add('koln,koln'); Staedte2.Add('koln,napoli'); Staedte2.Add('koln,nurnberg'); Staedte2.Add('napoli,berlin'); Staedte2.Add('napoli,dusseldorf'); Staedte2.Add('napoli,koln'); Staedte2.Add('napoli,napoli'); Staedte2.Add('napoli,nurnberg'); Staedte2.Add('nurnberg,berlin'); Staedte2.Add('nurnberg,dusseldorf'); Staedte2.Add('nurnberg,koln'); Staedte2.Add('nurnberg,napoli'); Staedte2.Add('nurnberg,nurnberg'); finally Staedte1.Free; Staedte2.Free; end; Mein erster kläglicher Versuch
Delphi-Quellcode:
Angezeigt bekomme ich nichts obwohl ich napoli sehen müsste.
for i := 0 to Staedte1.Count - 1 do
begin StadtListe1 := Staedte1.Strings[i]; StadtGefunden := False; for j := Staedte2.Count - 1 downto 0 do begin Stadt1 := Staedte2.Strings[j].Split([','])[0]; Stadt2 := Staedte2.Strings[j].Split([','])[1]; StadtGefunden := (Stadt1 = StadtListe1) or (Stadt2 = StadtListe1); if StadtGefunden then Break; end; if not StadtGefunden then ShowMessage(StadtListe1); end; |
AW: Zwei Listen filtern Denkproblem
Wie gesagt, abstrakt formuliert kommt man auf so etwas
Delphi-Quellcode:
PS Ja, ich weiß, dass es sich hier nicht wirklich um die Schnittmenge handelt und somit die Methode anders benannt werden müsste
program StadtVerwaltung;
{$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils, System.Generics.Defaults, System.Generics.Collections; type TArray = class(System.Generics.Collections.TArray) public class function &Intersect<T>(const A, B: array of T): TArray<T>; overload; class function &Intersect<T>(const A, B: array of T; const AComparer: IEqualityComparer<T>): TArray<T>; overload; end; { TArray } class function TArray.Intersect<T>(const A, B: array of T; const AComparer: IEqualityComparer<T>): TArray<T>; var vA, vB: T; begin Result := []; for vA in A do begin for vB in B do begin if AComparer.Equals(vA, vB) then begin Result := Result + [vA]; Break; end; end; end; end; class function TArray.Intersect<T>(const A, B: array of T): TArray<T>; begin Result := Intersect<T>(A, B, TEqualityComparer<T>.Default); end; procedure Main; var A, B, vBArr: TArray<string>; idx: Integer; begin A := ['a', 'b', 'c', 'd']; B := ['a,b', 'a,e,d']; for idx := Low(B) to High(B) do begin vBArr := B[idx].Split([',']); vBArr := TArray.Intersect<string>(vBArr, A); B[idx] := String.Join(',', vBArr); end; end; begin try { TODO -oUser -cConsole Main : Code hier einfügen } Main; except on E: Exception do Writeln(E.ClassName, ': ', E.Message); end; Readln; end. |
AW: Zwei Listen filtern Denkproblem
Danke für die Hilfe aber das hilft mir alle nicht weiter. Das ist wie mit Kanonen auf Spatzen schießen.
Hier sehe ich am Ende dusseldorf obwohl es in der Liste1 ist. Was ich sehen muss ist napoli damit alles was napoli beinhaltet raus kann.
Delphi-Quellcode:
Staedte1 := TStringList.Create;
Staedte2 := TStringList.Create; try // Liste 1 Staedte1.Add('berlin'); Staedte1.Add('dusseldorf'); // Liste 2 Staedte2.Add('berlin,berlin'); Staedte2.Add('berlin,dusseldorf'); Staedte2.Add('berlin,napoli'); Staedte2.Add('dusseldorf,berlin'); Staedte2.Add('dusseldorf,dusseldorf'); Staedte2.Add('dusseldorf,napoli'); Staedte2.Add('napoli,berlin'); Staedte2.Add('napoli,dusseldorf'); Staedte2.Add('napoli,napoli'); for j := Staedte2.Count - 1 downto 0 do begin Stadt1 := Staedte2.Strings[j].Split([','])[0]; Stadt2 := Staedte2.Strings[j].Split([','])[1]; LoescheStadt := False; for i := 0 to Staedte1.Count - 1 do begin StadtListe1 := Staedte1.Strings[i]; LoescheStadt := (StadtListe1 <> Stadt1) and (StadtListe1 <> Stadt2); if LoescheStadt then Break; end; if LoescheStadt then Staedte2.Delete(j); end; ShowMessage(Staedte2.Text); finally Staedte1.Free; Staedte2.Free; end; |
AW: Zwei Listen filtern Denkproblem
.. vielleicht ungefähr so, über eine dritte Liste.
Delphi-Quellcode:
for i:=0 to staedte1.count -1 do
for j:= 0 to staedte1.count -1 do begin idx := stadte2.indexOf(staedte1[i]+','+staedte1[j]); if idx > -1 then begin staedteTemp.add(staedte2[idx]); staedte2.delete(idx); end; end; Grüße Klaus |
AW: Zwei Listen filtern Denkproblem
Eine dritte Liste kann ich leider nicht anlegen. Alle notwendigen Informationen habe ich schon in einer unveränderbaren StringList und einer generischen TObjectList aus der herausgelöscht werden soll.
|
AW: Zwei Listen filtern Denkproblem
Delphi-Quellcode:
Ungetestet und auch nicht wirklich performant, müsste aber tun.
for j := Staedte2.Count - 1 downto 0 do
begin Stadt1 := Staedte2.Strings[j].Split([','])[0]; Stadt2 := Staedte2.Strings[j].Split([','])[1]; if (Staedte1.IndexOf(Stadt1) < 0) or (Staedte1.IndexOf(Stadt2) < 0) then Staedte2.Delete(j); end; |
AW: Zwei Listen filtern Denkproblem
Eine kurze Lösung und die verstehe ich zum Glück auch. Ich führe das nur ein mal aus. Es dauert zwar eine ganze Sekunde aber ich glaube das ist verkraftbar.
Schneller wär immer schön aber damit bin ich erst einmal zufrieden. Wäre es schneller die StringList durch eine TObjectList mit Klasseninstanzen zu ersetzen wo jede Klasse nur ein FCity: string hat? Die THashedStringList ist zwar schon etwas schneller aber auch nicht viel. |
AW: Zwei Listen filtern Denkproblem
Wieso nicht ungefähr so:
Delphi-Quellcode:
XD zu lange noch nebenbei was anderes gemacht^^ DeddyH war daher schneller und hat dei komplette Lösung^^
//Erst der Befehl zum lesen der einzelnen Städte
//dann folgende if abfrage if Stadte1.indexof('zu suchender Stadtname') = -1 then begin //Hier der Code zum löschen der Stadte in der Staedte2 StL end; |
AW: Zwei Listen filtern Denkproblem
Ich hatte auch einen zweiten Denkfehler drin. ich hatte um das IndexOf noch eine schleife die durch die StringList geht. Deswegen dauerte das auch 1 Sekunde.
|
AW: Zwei Listen filtern Denkproblem
Zitat:
Delphi-Quellcode:
Wenn man auf das Split verzichten will, kann man das alternativ auch mit dem NameValueSeparator erreichen:
var
dummy: Integer; tempArr: TArray<string>; ... Staedte1.Sorted := True; for j := Staedte2.Count - 1 downto 0 do begin tempArr := Staedte2[j].Split([',']); Stadt1 := tempArr[0]; Stadt2 := tempArr[1]; if not Staedte1.Find(Stadt1, dummy) or not Staedte1.Find(Stadt2) then Staedte2.Delete(j); end;
Delphi-Quellcode:
Staedte1.Sorted := True;
Staedte2.NameValueSeparator := ','; for j := Staedte2.Count - 1 downto 0 do begin Stadt1 := Staedte2.Names[j]; Stadt2 := Staedte2.ValueFromIndex[j]; if not Staedte1.Find(Stadt1, dummy) or not Staedte1.Find(Stadt2, dummy) then Staedte2.Delete(j); end; |
AW: Zwei Listen filtern Denkproblem
Zitat:
|
AW: Zwei Listen filtern Denkproblem
Zitat:
|
AW: Zwei Listen filtern Denkproblem
Eine Andere Idee hatte ich eben. Ich habe der Klasse der zweiten Liste ein Property verpasst was auf True gesetzt wird, wenn der Eintrag ignoriert werden soll.
Damit fällt das Löschen schon einmal weg. Ansonsten nutze ich jetzt die HashedStringList aus TIniFiles. Das dauert jetzt alles keinen Wimpernschlag mehr. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:01 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz