| Autor |
Beitrag |
Airtrox
      
Beiträge: 109
Delphi 7
|
Verfasst: Di 22.09.09 12:54
hey
ich habe wieder mal eine frage:
Ich möchte ein einfaches programm, das nur ein Memo enthällt, in dem die Zeilen ab einer bestimmten Position geordnet werden sollen. Also sollte aus so einer stringlist
asdhj_asd
8ejdu_bdf
a84jd_kkk
erst ab dem Unterstrich sortiert werden. Soweit sogut, das Problem ist nur, dass die zeichen vorher erhalten bleiben sollen.
Ich habe mir gedacht, dass ich in einer schleife erst alles vornedran lösche und seperat speichere und gleichzeitig am ende der zeile eine Nummer oder was anderes setze, sodass ich die gespeicherten zeichen von vorne später wieder zuweisen kann, nachdem sie sortiert wurden.
In der Praxis halte ich diese Idee jedoch nicht für so gut, wollte deshalb mal eure Vorschläge hören.
lg
|
|
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Di 22.09.09 13:17
Berücksichtige doch in der Vergleichsroutine einfach nur das, was nach dem Unterstrich kommt. Such ihn mit pos und kopiere dir den Rest mit copy raus.
|
|
Airtrox 
      
Beiträge: 109
Delphi 7
|
Verfasst: Di 22.09.09 13:27
das war ja auch meine idee, das problem ist aber, dass ich erstmal alles ab dem Unterstrich kopieren müsste (in einen neuen String), dannn mit sort() sortieren und als ausgabe soll wieder die ganze Zeile da stehen, jedoch geordnet ab dem _
|
|
Narses
      

Beiträge: 10183
Erhaltene Danke: 1256
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Di 22.09.09 13:27
Moin!
Wenn du nur wenige Einträge in dem Memo hast, ist der Vorschlag von Luckie völlig OK.
Wenn es sehr viele Zeilen sind, Ansatz: - Mach eine temporäre Stringliste auf, z.B. var SL: TStringList;
- Geh das Memo durch und lege den zu sortierenden Teil der Zeilen in der Stringliste ab, dabei beim Anfügen in dem .Objects[] des Eintrags den aktuellen Index ablegen
jetzt steht in der Stringliste der Teil, der Sortiert werden soll und im zugehörigen .Objects[] die Zeile, aus der der Text stammt
- Die Stringliste sortieren: SL.Sort; (dabei werden die Objects mit getauscht)
- Jetzt die Stringliste durchgehen und die Indizes auf das Memo übertragen:
Delphi-Quelltext 1: 2:
| for i := 0 to SL.Count-1 do Memo1.Lines.Objects[Integer(SL.Objects[i])] := Pointer(i); | - Anschließend das Memo nach den .Lines.Objects[] custom-sortieren - fertig.
cu
Narses
//EDIT: Airtrox hat folgendes geschrieben : | | das war ja auch meine idee, das problem ist aber, dass ich erstmal alles ab dem Unterstrich kopieren müsste (in einen neuen String), dannn mit sort() sortieren und als ausgabe soll wieder die ganze Zeile da stehen, jedoch geordnet ab dem _ |
Ich schätze mal Luckie meinte, du solltest eine Vergleichsfunktion für .CustomSort schreiben, die das gewünschte Vergleichsresultat "on-the-fly" bestimmt. 
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Di 22.09.09 13:46
|
|
Airtrox 
      
Beiträge: 109
Delphi 7
|
Verfasst: Di 22.09.09 14:39
Hey,
danke für den Vorschlag, ich verstehe das auch soweit, nur bei diese Zeile bin ich etwas ratlos:
| Zitat: | Geh das Memo durch und lege den zu sortierenden Teil der Zeilen in der Stringliste ab, dabei beim Anfügen in dem .Objects[] des Eintrags den aktuellen Index ablegen jetzt steht in der Stringliste der Teil, der Sortiert werden soll und im zugehörigen .Objects[] die Zeile, aus der der Text stammt |
Könntest du das etwas genauer erläutern, evt. mit einem Beispiel?
lg
|
|
Narses
      

Beiträge: 10183
Erhaltene Danke: 1256
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Di 22.09.09 15:18
Moin!
Airtrox hat folgendes geschrieben : | | Könntest du das etwas genauer erläutern, evt. mit einem Beispiel? |
Delphi-Quelltext 1: 2:
| for i := 0 to Memo1.Lines.Count-1 do SL.AddObject(Copy(Memo1.Lines.Strings[i],5,4),Pointer(i)); | Das Markierte ist natürlich entspreched anzupassen, je nach dem, welchen Teil der Strings du extrahieren willst.
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
Dude566
      
Beiträge: 1592
Erhaltene Danke: 79
W8, W7 (Chrome, FF, IE)
Delphi XE2 Pro, Eclipse Juno, VS2012
|
Verfasst: Di 22.09.09 17:15
Airtrox hat folgendes geschrieben : | | das war ja auch meine idee, das problem ist aber, dass ich erstmal alles ab dem Unterstrich kopieren müsste (in einen neuen String), dannn mit sort() sortieren und als ausgabe soll wieder die ganze Zeile da stehen, jedoch geordnet ab dem _ |
Und wo ist das Problem beide nach dem Sortieren wieder zu einem zu vereinen?
_________________ Es gibt 10 Gruppen von Menschen: diejenigen, die das Binärsystem verstehen, und die anderen.
|
|
Airtrox 
      
Beiträge: 109
Delphi 7
|
Verfasst: Di 22.09.09 19:23
An Narses:
Wird dabei in die Stringlist also nur der Teil ab Position 5 (in deinem Bsp) kopiert? Und dann eben mit SL.sort sortiert?
Dann noch eine kleine Frage: Wenn also der die Stringlist sortiert ist, wie hänge ich den ersten Teil den Sortierten Zeilen wieder hinzu? Verstehe das noch nicht so ganz 
|
|
Narses
      

Beiträge: 10183
Erhaltene Danke: 1256
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Di 22.09.09 19:24
Moin!
Airtrox hat folgendes geschrieben : | Ich möchte ein einfaches programm, das nur ein Memo enthällt, in dem die Zeilen ab einer bestimmten Position geordnet werden sollen. Also sollte aus so einer stringlist
asdhj_asd
8ejdu_bdf
a84jd_kkk
erst ab dem Unterstrich sortiert werden. Soweit sogut, das Problem ist nur, dass die zeichen vorher erhalten bleiben sollen. |
Also wenn ich mir das alles nochmal durch den Kopf gehen lasse, dann sind die ganzen Ansätze für den Eimer, weil hier mal wieder die GUI als Datenlager missbraucht wird.  Offensichtlich handelt es sich bei den Memo-Zeilen um eine kombinierte Ausgabe verschiedener Werte. Warum also das Pferd von Hinten aufzäumen, wenn man das auch gleich richtig machen kann:  - Die Werte getrennt speichern, z.B. in einer TList, die records verwaltet oder gleich in einer TObjectList, die passende Objekte verwaltet
- Den Container sortieren (also die TList bzw. TObjectList)
- Dann die Ausgabe im Memo durch Ersetzen des Inhalts neu erzeugen
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
Airtrox 
      
Beiträge: 109
Delphi 7
|
Verfasst: Di 22.09.09 21:42
Narses hat folgendes geschrieben : | Moin!
- Die Werte getrennt speichern, z.B. in einer TList, die records verwaltet oder gleich in einer TObjectList, die passende Objekte verwaltet
- Den Container sortieren (also die TList bzw. TObjectList)
- Dann die Ausgabe im Memo durch Ersetzen des Inhalts neu erzeugen
|
Da hörts bei mir auf^^ Punkt2 sollte mit SL.sort ja klappen, Punkt3 ist auch klar (neu zuweisen), aber bei dem Rest wäre ich ratlos, wie ich das hinbekommen könnte...
|
|
Narses
      

Beiträge: 10183
Erhaltene Danke: 1256
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Di 22.09.09 22:25
Moin!
Dann hier mal ein Beispiel:
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: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79:
| type TElement = class(TObject) private FStr1: String; FStr2: String; function GetAsStr: String; public constructor Create(const S1, S2: String); property Str1: String read FStr1 write FStr1; property Str2: String read FStr2 write FStr2; property AsStr: String read GetAsStr; end;
TForm1 = class(TForm) Memo1: TMemo; Button1: TButton; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure Button1Click(Sender: TObject); private public ElementList: TObjectList; end;
constructor TElement.Create(const S1, S2: String); begin inherited Create; FStr1 := S1; FStr2 := S2; end;
function TElement.GetAsStr: String; begin Result := FStr1+'_'+FStr2; end;
function MyCompare(Item1, Item2: Pointer): Integer; begin Result := CompareStr(TElement(Item1).Str2,TElement(Item2).Str2); end;
procedure TForm1.FormCreate(Sender: TObject); begin Randomize; ElementList := TObjectList.Create; end;
procedure TForm1.FormDestroy(Sender: TObject); begin ElementList.Free; end;
procedure TForm1.Button1Click(Sender: TObject); var i: Integer;
function RandStr(const Len: Integer): String; var i: Integer; begin SetLength(Result,Len); for i := 1 to Len do Result[i] := Char(Random(26)+Ord('A')); end;
begin ElementList.Clear; for i := 1 to Random(10)+2 do ElementList.Add(TElement.Create(RandStr(5),RandStr(8))); ElementList.Sort(MyCompare); Memo1.Clear; for i := 0 to ElementList.Count-1 do Memo1.Lines.Add(TElement(ElementList.Items[i]).AsStr); end; | cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
Airtrox 
      
Beiträge: 109
Delphi 7
|
Verfasst: Mi 23.09.09 13:04
Dabei bekomme ich die Fehlermeldung:
die unit Contnrs hab ich miteingebunden.
Moderiert von Narses: Bild als Anhang hochgeladen.
Einloggen, um Attachments anzusehen!
|
|
Narses
      

Beiträge: 10183
Erhaltene Danke: 1256
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Mi 23.09.09 13:14
Moin!
Ähm  das ist kein c&p-Code, etwas Anpassung von dir auf dein Projekt muss ich schon erwarten können...
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
Airtrox 
      
Beiträge: 109
Delphi 7
|
Verfasst: Mi 23.09.09 13:35
Da hast du absolut Recht, aber ich muss ehrlich sagen, dass ich den Quelltext sogut wie gar nicht bzw. nur in kleinen Teilen verstehe, deshalb wüsste ich auch nicht wirklich wo ich es eben anpassen muss 
|
|
Narses
      

Beiträge: 10183
Erhaltene Danke: 1256
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Mi 23.09.09 13:59
Moin!
Airtrox hat folgendes geschrieben : | ich muss ehrlich sagen, dass ich den Quelltext sogut wie gar nicht bzw. nur in kleinen Teilen verstehe, deshalb wüsste ich auch nicht wirklich wo ich es eben anpassen muss  |
OK, dann noch etwas ausführlicher.
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: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92:
| type TElement = class(TObject) private FStr1: String; FStr2: String; function GetAsStr: String; public constructor Create(const S1, S2: String); property Str1: String read FStr1 write FStr1; property Str2: String read FStr2 write FStr2; property AsStr: String read GetAsStr; end;
TForm1 = class(TForm) Memo1: TMemo; Button1: TButton; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure Button1Click(Sender: TObject); private public ElementList: TObjectList; end;
constructor TElement.Create(const S1, S2: String); begin inherited Create; FStr1 := S1; FStr2 := S2; end;
function TElement.GetAsStr: String; begin Result := FStr1+'_'+FStr2; end;
function MyCompare(Item1, Item2: Pointer): Integer; begin Result := CompareStr(TElement(Item1).Str2,TElement(Item2).Str2); end;
procedure TForm1.FormCreate(Sender: TObject); begin Randomize; ElementList := TObjectList.Create; end;
procedure TForm1.FormDestroy(Sender: TObject); begin ElementList.Free; end;
procedure TForm1.Button1Click(Sender: TObject); var i: Integer;
function RandStr(const Len: Integer): String; var i: Integer; begin SetLength(Result,Len); for i := 1 to Len do Result[i] := Char(Random(26)+Ord('A')); end;
begin ElementList.Clear; for i := 1 to Random(10)+2 do ElementList.Add( TElement.Create( RandStr(5), RandStr(8) ) ); ElementList.Sort(MyCompare); Memo1.Clear; for i := 0 to ElementList.Count-1 do Memo1.Lines.Add(TElement(ElementList.Items[i]).AsStr); end; | cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|