![]() |
Pfade in TStrings abbilden...
Guten Morgen
Ich habe eine Liste mit Pfaden: z.B. (Originalliste)
SQL-Code:
GG_OWA-Access
GG_Axioma GG_Winbau zz_alle Direktion P\+F zz_alle Informatikdienste GG_Vitruviusdaten RG_PC_Inventar_Daten GG_AbuWin GG_IDT_IC GG_IDT GG_IDT_IC|GG_SWF-Spec GG_IDT_IC|RG_IDT_WSUS_Admin GG_IDT_IC|GG_PEKAUsers GG_IDT_IC|RG_FV_Matrix GG_IDT_IC|RG_P_F_Matrix GG_IDT_IC|GG_WINAG GG_IDT_IC|RG_FV_Public GG_IDT_IC|RG_P_F_Public GG_IDT_IC|GG_FV GG_IDT_IC|GG_FV|RG_Scan_FV GG_IDT_IC|GG_FV|RG_FV_Matrix GG_IDT_IC|GG_FV|RG_P_F_Matrix GG_IDT_IC|GG_FV|RG_FV_Public GG_IDT_IC|GG_FV|RG_P_F_Public GG_IDT_IC|GG_FV|RG_P_F GG_IDT_IC|RG_P_F GG_IDT_IC|RG_FV GG_IDT_IC|RG_IC GG_IDT_IC|RG_Museumplus GG_IDT|GG_Mobile-Access GG_IDT|RG_EVA GG_IDT|GG_SWF-MM GG_IDT|GG_Axioma GG_IDT|RG_Scan_IDT GG_IDT|GG_rbiAusmass GG_IDT|RG_rbiAusmass GG_IDT|GG_Teamviewer GG_IDT|RG_Balance GG_IDT|RG_PROJ_ICT-Schulen GG_IDT|GG_RealAudio-Access GG_IDT|GG_FTP-Access GG_IDT|RG_HW_Inventar_Daten GG_IDT|GG_AbacusUsers GG_IDT|GG_NestUsers GG_IDT|RG_FV_Matrix GG_IDT|RG_P_F_Matrix GG_IDT|GG_Alle-StadtThun GG_IDT|RG_PC_Inventar_Daten_R GG_IDT|RG_Taxme_TBA GG_IDT|RG_Taxme_SuI GG_IDT|RG_Taxme_SO GG_IDT|RG_FV_Public GG_IDT|RG_P_F_Public GG_IDT|GG_FV GG_IDT|GG_FV|RG_Scan_FV GG_IDT|GG_FV|RG_FV_Matrix GG_IDT|GG_FV|RG_P_F_Matrix GG_IDT|GG_FV|RG_FV_Public GG_IDT|GG_FV|RG_P_F_Public GG_IDT|GG_FV|RG_P_F GG_IDT|RG_P_F GG_IDT|RG_Taxme GG_IDT|RG_IC_R GG_IDT|RG_TC_R GG_IDT|RG_SC_R GG_IDT|RG_FV GG_IDT|RG_IDT Diese versuche ich nun in einer anderen Liste korrekt abzubilden, mit Korrekt meine ich: Der Eingangsreihenfolge entsprechend, aber mit Korrekter Struktur. Wie in der oberen Liste entnehmen kann, ist eigentlich nur GG_IDT fehl am Platz. Die zweite Ebene kommt bereits korrekt daher... Das Ergebnis sollte aber nun so ausschauen: (so sollte es am Schluss ausschauen Liste)
SQL-Code:
Ich habs mal mit untenstehendem Code versucht. Lustig ist nur, das jetzt zwar die Erste Ebene stimmt, aber die Zweite Ebene
GG_OWA-Access
GG_Axioma GG_Winbau zz_alle Direktion P\+F zz_alle Informatikdienste GG_Vitruviusdaten RG_PC_Inventar_Daten GG_AbuWin GG_IDT_IC GG_IDT_IC|GG_SWF-Spec GG_IDT_IC|RG_IDT_WSUS_Admin GG_IDT_IC|GG_PEKAUsers GG_IDT_IC|RG_FV_Matrix GG_IDT_IC|RG_P_F_Matrix GG_IDT_IC|GG_WINAG GG_IDT_IC|RG_FV_Public GG_IDT_IC|RG_P_F_Public GG_IDT_IC|GG_FV GG_IDT_IC|GG_FV|RG_Scan_FV GG_IDT_IC|GG_FV|RG_FV_Matrix GG_IDT_IC|GG_FV|RG_P_F_Matrix GG_IDT_IC|GG_FV|RG_FV_Public GG_IDT_IC|GG_FV|RG_P_F_Public GG_IDT_IC|GG_FV|RG_P_F GG_IDT_IC|RG_P_F GG_IDT_IC|RG_FV GG_IDT_IC|RG_IC GG_IDT_IC|RG_Museumplus GG_IDT GG_IDT|GG_Mobile-Access GG_IDT|RG_EVA GG_IDT|GG_SWF-MM GG_IDT|GG_Axioma GG_IDT|RG_Scan_IDT GG_IDT|GG_rbiAusmass GG_IDT|RG_rbiAusmass GG_IDT|GG_Teamviewer GG_IDT|RG_Balance GG_IDT|RG_PROJ_ICT-Schulen GG_IDT|GG_RealAudio-Access GG_IDT|GG_FTP-Access GG_IDT|RG_HW_Inventar_Daten GG_IDT|GG_AbacusUsers GG_IDT|GG_NestUsers GG_IDT|RG_FV_Matrix GG_IDT|RG_P_F_Matrix GG_IDT|GG_Alle-StadtThun GG_IDT|RG_PC_Inventar_Daten_R GG_IDT|RG_Taxme_TBA GG_IDT|RG_Taxme_SuI GG_IDT|RG_Taxme_SO GG_IDT|RG_FV_Public GG_IDT|RG_P_F_Public GG_IDT|GG_FV GG_IDT|GG_FV|RG_Scan_FV GG_IDT|GG_FV|RG_FV_Matrix GG_IDT|GG_FV|RG_P_F_Matrix GG_IDT|GG_FV|RG_FV_Public GG_IDT|GG_FV|RG_P_F_Public GG_IDT|GG_FV|RG_P_F GG_IDT|RG_P_F GG_IDT|RG_Taxme GG_IDT|RG_IC_R GG_IDT|RG_TC_R GG_IDT|RG_SC_R GG_IDT|RG_FV GG_IDT|RG_IDT wird nun strukturell nicht richtig dargestellt.
Delphi-Quellcode:
Dieser Code führt zu diesem Ergebnis:
procedure TForm1.ForceListItems(sliList:TStrings; sliPath: String; sliPathDelim:Char);
var sL: TStringList; I: Integer; index: Integer; path: String; begin sL := TStringList.Create; try path := sliPath; // ersetze den delimiter mit einem zeilenumbruch for I := 1 to Length(sliPath) do if sliPath[i] = sliPathDelim then sliPath[i] := #13; // der pfad lässt sich nun in den einzelnen elementen // in eine liste schreiben sL.Text := sliPath; for I := 0 to sL.Count - 1 do begin if sliList.IndexOf(sL[i]) = -1 then begin if (index > 0) then sliList.Insert(index,path) else sliList.Add(path); end else index := sliList.IndexOf(sL[i]) + 1; end; finally FreeAndNil(sL); end; end;
SQL-Code:
Man beachte die Fehler : "GG_IDT_IC|GG_FV" und "GG_IDT|GG_FV" Stehen zu weit unten...
GG_OWA-Access
GG_Axioma GG_Winbau zz_alle Direktion P\+F zz_alle Informatikdienste GG_Vitruviusdaten RG_PC_Inventar_Daten GG_AbuWin GG_IDT_IC GG_IDT_IC|RG_Museumplus GG_IDT_IC|RG_IC GG_IDT_IC|RG_FV GG_IDT_IC|RG_P_F GG_IDT_IC|GG_FV|RG_P_F GG_IDT_IC|GG_FV|RG_P_F GG_IDT_IC|GG_FV|RG_P_F_Public GG_IDT_IC|GG_FV|RG_P_F_Public GG_IDT_IC|GG_FV|RG_FV_Public GG_IDT_IC|GG_FV|RG_FV_Public GG_IDT_IC|GG_FV|RG_P_F_Matrix GG_IDT_IC|GG_FV|RG_P_F_Matrix GG_IDT_IC|GG_FV|RG_FV_Matrix GG_IDT_IC|GG_FV|RG_FV_Matrix GG_IDT_IC|GG_FV|RG_Scan_FV GG_IDT_IC|GG_FV|RG_Scan_FV GG_IDT_IC|GG_FV GG_IDT_IC|RG_P_F_Public GG_IDT_IC|RG_FV_Public GG_IDT_IC|GG_WINAG GG_IDT_IC|RG_P_F_Matrix GG_IDT_IC|RG_FV_Matrix GG_IDT_IC|GG_PEKAUsers GG_IDT_IC|RG_IDT_WSUS_Admin GG_IDT_IC|GG_SWF-Spec GG_IDT GG_IDT|RG_IDT GG_IDT|RG_FV GG_IDT|RG_SC_R GG_IDT|RG_TC_R GG_IDT|RG_IC_R GG_IDT|RG_Taxme GG_IDT|RG_P_F GG_IDT|GG_FV|RG_P_F GG_IDT|GG_FV|RG_P_F GG_IDT|GG_FV|RG_P_F_Public GG_IDT|GG_FV|RG_P_F_Public GG_IDT|GG_FV|RG_FV_Public GG_IDT|GG_FV|RG_FV_Public GG_IDT|GG_FV|RG_P_F_Matrix GG_IDT|GG_FV|RG_P_F_Matrix GG_IDT|GG_FV|RG_FV_Matrix GG_IDT|GG_FV|RG_FV_Matrix GG_IDT|GG_FV|RG_Scan_FV GG_IDT|GG_FV|RG_Scan_FV GG_IDT|GG_FV GG_IDT|RG_P_F_Public GG_IDT|RG_FV_Public GG_IDT|RG_Taxme_SO GG_IDT|RG_Taxme_SuI GG_IDT|RG_Taxme_TBA GG_IDT|RG_PC_Inventar_Daten_R GG_IDT|GG_Alle-StadtThun GG_IDT|RG_P_F_Matrix GG_IDT|RG_FV_Matrix GG_IDT|GG_NestUsers GG_IDT|GG_AbacusUsers GG_IDT|RG_HW_Inventar_Daten GG_IDT|GG_FTP-Access GG_IDT|GG_RealAudio-Access GG_IDT|RG_PROJ_ICT-Schulen GG_IDT|RG_Balance GG_IDT|GG_Teamviewer GG_IDT|RG_rbiAusmass GG_IDT|GG_rbiAusmass GG_IDT|RG_Scan_IDT GG_IDT|GG_SWF-MM GG_IDT|RG_EVA GG_IDT|GG_Mobile-Access Nun wie modifiziere ich den Code um das gewünschte Ergebnis zu erhalten? :cat: |
Re: Pfade in TStrings abbilden...
|
Re: Pfade in TStrings abbilden...
Zitat:
|
Re: Pfade in TStrings abbilden...
Und
![]() Zitat:
|
Re: Pfade in TStrings abbilden...
Zitat:
Denn das problem ist schon komplizierter als es auf den ersten Blick erscheint. Ich habe schon etliche Stunden damit verbracht. Denn Ich habe ja kaum anhaltspünkte um Einträge zu vergleichen, die Reihenfolge soll ja erstmal so bleiben wie sie ist, nur die Struktur soll korrekt dargestellt werden. Vielleicht kannst du mit ein Beispiel geben wie das mit custom sort funktionieren könnte ?! ich bin nähmlich langsam am Ende meines Lateins... |
Re: Pfade in TStrings abbilden...
Im Prinzip brauchst du doch die Strings einfach nur CaseInsensitiv (zur Sicherheit) alphabetisch sortieren.
|
Re: Pfade in TStrings abbilden...
Zitat:
siehe "Original Liste" und "so sollte es am Schluss ausschauen Liste" ! |
Re: Pfade in TStrings abbilden...
@TE: Wenn ich dich jetzt richtig verstehe, möchtest Du, dass alle Verzeichnisse von Ebene A aufgelistet werden und unter diese alle Verzeichnisse der ebene B einsortiert werden, ohne dass die Reihenfolge vertauscht wird.
Ist das soweit richtig? Gruß Thomas |
Re: Pfade in TStrings abbilden...
genau das meine ich...
|
Re: Pfade in TStrings abbilden...
können die Unterverzeichnisse wenigstens Alphabetisch sortiert sein, bzw. können die sogar in 'ner anderen womöglich anders "sortierten" Reinfolge sein, oder müssen die auch in ihrer
Reinfolge bleiben? wenn die Unterverzeichnisse auch in ihrer Reinfolge bleiben sollen, dann wär's wohl am Einfachsten das Ganze in 'nen Baum zu zerlegen und danach neu wieder zusammenzusetzen. |
Re: Pfade in TStrings abbilden...
Zitat:
Zitat:
Würdet ihr das so lassen oder findet ihr das auch unschön? |
Re: Pfade in TStrings abbilden...
Hallo,
[OT]In der Zeit, die ich für meinen Vorschlag gebraucht habe, ist die Diskussion schon weit fortgeschritten, daher könnte es sein, dass das folgende schon "veraltet" ist. Schicke den Text aber trotzdem noch ab, eventuell ist ja doch noch ein Denkanstoß zur Problemlösung drin.[/OT] schau Dir bitte nochmal die Routine an:
Delphi-Quellcode:
Mir scheint, dass index nicht initialisiert ist, dies könnte zu der unerwünschten Reihenfolge führen. Zumindest beim ersten Durchgang kann ein Fehler auftreten, wenn sliList.IndexOf(sL[i]) = -1 ist.
procedure TForm1.ForceListItems(sliList:TStrings; sliPath: String; sliPathDelim:Char);
var sL: TStringList; I: Integer; index: Integer; path: String; begin sL := TStringList.Create; try path := sliPath; // ersetze den delimiter mit einem zeilenumbruch for I := 1 to Length(sliPath) do if sliPath[i] = sliPathDelim then sliPath[i] := #13; // der pfad lässt sich nun in den einzelnen elementen // in eine liste schreiben sL.Text := sliPath; for I := 0 to sL.Count - 1 do begin if sliList.IndexOf(sL[i]) = -1 then begin if (index > 0) then sliList.Insert(index,path) else sliList.Add(path); end else index := sliList.IndexOf(sL[i]) + 1; end; finally FreeAndNil(sL); end; end; Wenn ich das bisher richtig sehe, kommst Du nicht um eine eigene Sortierroutine herum, hier hilft Dir dann CustomSort. Schau mal bitte hier ![]() Vermutlich kannst Du Deine Liste nicht an "einem Stück" sortieren, sondern musst da Teilbereiche sortieren, also z. B. aller Einträge die mit GG_IDT_IC beginnen für sich, die mit GG_IDT beginnen für sich... Beim CustomSort kannst Du eine eigene Sortierroutine nutzen, die dies berücksichtigt.
Code:
Wenn man sich diesen Ausschnitt aus der "Soll"-Sortierung anschaut, kommt man nicht umhin, eine eigene Vergleichsoperation für Größer und Kleiner zu implementieren. Eine rein alphabetische Sortierung reicht hier sicherlich nicht aus.
// Auszug aus Sollsortierung
GG_IDT|RG_P_F GG_IDT|RG_Taxme GG_IDT|RG_IC_R GG_IDT|RG_TC_R GG_IDT|RG_SC_R GG_IDT|RG_FV GG_IDT|RG_IDT Mal noch eine "Spielidee": Wenn die Originalliste, so wie sie im Eingangspost steht, vollständig ist, könntest Du hergehen, Dir ein Array bauen, das diese Liste enthält und zusätzlich noch einen Integerwert für die Reihenfolge. Das könnte dann eventuell so aussehen:
Delphi-Quellcode:
Nun kannst Du hergehen und in PfadListe[i].sPfad nach der Zeichenfolge suchen und über PfadListe[i].iReihenFolge die Position in im Ergebnis bestimmen.
Type
trcPfadListe = Record sPfad : String; iReihenFolge : Integer; end; tPfadListe = Array[0..255] of trcPfadListe; var Pfadliste : tPfadListe; begin PfadListe[ 0].sPfad := 'GG_AbuWin'; PfadListe[ 0].iReihenFolge := 7; PfadListe[ 1].sPfad := 'GG_Axioma'; PfadListe[ 1].iReihenFolge := 1; PfadListe[ 2].sPfad := 'GG_IDT_IC'; PfadListe[ 2].iReihenFolge := 8; PfadListe[ 3].sPfad := 'GG_IDT_IC|GG_PEKAUsers'; PfadListe[ 3].iReihenFolge := 11; PfadListe[ 4].sPfad := 'GG_IDT_IC|GG_SWF-Spec'; PfadListe[ 4].iReihenFolge := 9; PfadListe[ 5].sPfad := 'GG_IDT_IC|GG_WINAG'; PfadListe[ 5].iReihenFolge := 14; PfadListe[ 6].sPfad := 'GG_IDT_IC|RG_FV_Matrix'; PfadListe[ 6].iReihenFolge := 12; PfadListe[ 7].sPfad := 'GG_IDT_IC|RG_FV_Public'; PfadListe[ 7].iReihenFolge := 15; PfadListe[ 8].sPfad := 'GG_IDT_IC|RG_IDT_WSUS_Admin'; PfadListe[ 8].iReihenFolge := 10; PfadListe[ 9].sPfad := 'GG_IDT_IC|RG_P_F_Matrix'; PfadListe[ 9].iReihenFolge := 13; PfadListe[10].sPfad := 'GG_IDT_IC|RG_P_F_Public'; PfadListe[10].iReihenFolge := 16; PfadListe[11].sPfad := 'GG_OWA-Access'; PfadListe[11].iReihenFolge := 0; PfadListe[12].sPfad := 'GG_Vitruviusdaten'; PfadListe[12].iReihenFolge := 5; PfadListe[13].sPfad := 'GG_Winbau'; PfadListe[13].iReihenFolge := 2; PfadListe[14].sPfad := 'RG_PC_Inventar_Daten'; PfadListe[14].iReihenFolge := 6; PfadListe[15].sPfad := 'zz_alle Direktion P\+F'; PfadListe[15].iReihenFolge := 3; PfadListe[16].sPfad := 'zz_alle Informatikdienste'; PfadListe[16].iReihenFolge := 4; Ob das jetzt eine elegante Lösung ist? Weiß nicht so recht. |
Re: Pfade in TStrings abbilden...
Zitat:
s funktioniert prima und ist noch dazu gar nicht mal so langsam... Aber trotzdem irgendwie unschön oder? |
Re: Pfade in TStrings abbilden...
du mußt ja keinen echten VCL-Baum nutzen :zwinker: (binäre Bäumchen)
|
Re: Pfade in TStrings abbilden...
Zitat:
|
Re: Pfade in TStrings abbilden...
Zitat:
[add] ob's richtig ist, weiß ich jetzt nicht, aber es wirft zumindestens keine exception
Delphi-Quellcode:
Type PMyPath = ^TMyPath;
TMyPath = Record Name: String; Child: PMyPath; Next: PMyPath; End; Procedure TForm1.ForceListItems(sliList: TStrings; sliPathDelim: Char); Procedure Add(Var Root: PMyPath; S3: String); Var DelRoot: PMyPath; Begin sliList.Add(S3 + Root.Name); While Assigned(Root.Child) do Add(Root.Child, S3 + Root.Name + sliPathDelim); DelRoot := Root; Root := Root.Next; Dispose(DelRoot); End; Var Root, Temp, Temp2: PMyPath; TempRoot: ^PMyPath; S, S2: String; i: Integer; Begin // in Baum zerlegen Root := nil; While sliList.Count > 0 do Begin // Pfad zerlegen S := sliList[0]; sliList.Delete(0); TempRoot := @Root; While S > '' do Begin // Pfadteil extrahieren i := Pos(sliPathDelim, S + sliPathDelim); S2 := Copy(S, 1, i - 1); Delete(S, 1, i); // schauen ob's den schon gibt Temp := TempRoot^; While Assigned(Temp) and not SameText(Temp.Name, S2) do Temp := Temp.Next; If not Assigned(Temp) Then Begin // wenn nicht, dann erstellen New(Temp); Temp.Name := S2; Temp.Child := nil; Temp.Next := nil; // ist es der erste Subpfad? If Assigned(TempRoot^) Then Begin nein, dann hinten dranhängen Temp2 := TempRoot^; While Assigned(Temp2.Next) do Temp2 := Temp2.Next; Temp2.Next := Temp; TempRoot := @Temp.Child; End Else TempRoot^ := Temp; // ja, dann eintragen End Else TempRoot := @Temp.Child; // wenn dann weiter mit diesem End; End; // dat Zusammensetzen, hab ich einfach mal rekursiv gelöst, // sonst hätt noch 'ne Variable benötigt, oder die Liste noch // mehr verketten müssen (war so einfacher :oops: ) While Assigned(Root) do Add(Root, ''); End; Procedure TForm1.FormCreate(Sender: TObject); Begin ForceListItems(Memo1.Lines, '|'); End; |
Re: Pfade in TStrings abbilden...
Also ich möchte jetzt son binären Baum... aber keine Ahnung wie man sowas macht?!
Hab ![]() |
Re: Pfade in TStrings abbilden...
das da oben ist schon 'nen kleines Bäumchen :zwinker:
|
Re: Pfade in TStrings abbilden...
Zitat:
und was hälst du von dem ![]() was ist jetzt besser? schönes WE euch allen |
Re: Pfade in TStrings abbilden...
im Prinzip ist das fast das selbe, nur daß in dem Link eine Doppelt verkettete Liste ist nd diese auf einer Klasse aufbaut.
die eine (Rückwärts)Verkettung könnte könnte man notfalls weglassen (wird hier nicht unbedingt gebraucht). was jetzt besser ist, müßtest du entscheiden, also was dir besser gefällt. es sind Beides kleine Objekte/Records, welche miteinander verknüpft werden. PS: mir fällt grad auf, daß ich da oben das Freigeben vergessen hab :oops: sowas sollte man vielleicht auch noch einbauen, also den Speicher wieder freigeben. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:02 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-2025 by Thomas Breitkreuz