Entwickler-Ecke
Grafische Benutzeroberflächen (VCL & FireMonkey) - Stringlist ab bestimmter Position sortieren
Airtrox - Di 22.09.09 12:54
Titel: Stringlist ab bestimmter Position sortieren
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
Delete - 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 - 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 - 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 :arrow: 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. :idea:
Airtrox - 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 :arrow: 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 - 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. :idea: ;)
cu
Narses
Dude566 - 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?
Airtrox - 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 - 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
Airtrox - 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 - Di 22.09.09 22:25
Moin!
Dann hier mal ein Beispiel: ;)
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: 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
Airtrox - Mi 23.09.09 13:04
Dabei bekomme ich die Fehlermeldung:
die unit Contnrs hab ich miteingebunden.
Moderiert von
Narses: Bild als Anhang hochgeladen.
Narses - 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
Airtrox - 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 - 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. ;)
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: 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
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 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!