AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi Synonyme Bezeichnungen für eine Objekt-Eigenschaft
Thema durchsuchen
Ansicht
Themen-Optionen

Synonyme Bezeichnungen für eine Objekt-Eigenschaft

Ein Thema von Gausi · begonnen am 27. Jul 2006 · letzter Beitrag vom 17. Aug 2006
Antwort Antwort
Benutzerbild von Gausi
Gausi

Registriert seit: 17. Jul 2005
877 Beiträge
 
Delphi 11 Alexandria
 
#1

Synonyme Bezeichnungen für eine Objekt-Eigenschaft

  Alt 27. Jul 2006, 17:31
Ich habe eine Klasse TAudioFile mit verschiedenen Eigenschaften, z.B. Artist, Titel, Album etc. (für diese Problemstellung hier alles nur Strings).

Jetzt stellt sich mir das Problem, dass ich eine Liste von solchen Objekten sortieren möchte, und zwar nicht nur nach einem Sortierkriterium, sondern nach mehreren, die der User zur Laufzeit festlegen kann. Also z.B. primäres Sortierkriterium: Artist. Bei Gleichheit: Sortierung nach Album, anschließend Sortierung nach Titel.

Wenn ich 10 Eigenschaften habe, müsste ich also 10*9 = 90 Compare-Funktionen für die Sort-Routine schreiben , wenn ich zwei "Stufen" zulasse. Bei 3 Stufen (wie im Beispiel) 10*9*8 = 720....

Im DF ist die Idee aufgekommen, das damit zu lösen, alle Eigenschaften des Objektes in einem Array of String zu speichern, und in einer Comparefunktion auf ein Sortier-Array zurückzugreifen, in dem die Indizes der Eigenschaften gespeichert sind, nach denen primär, sekundär, etc. sortiert wird.
Ist sicherlich ne schöne Sache, nur würde diese Lösung bedeuten, dass ich in einem recht umfangreichen Projekt alle ".Artist", ".Album" etc. durch ein ".EigenschaftenArray[CONST_ARTIST]" etc. ersetzen müsste (mit entsprechenden Konstanten CONST_ARTIST). Ein zusätzlicher großer Nachteil wäre auch, dass man Dinge wie Autovervollständigung in der IDE zum schnelleren Finden der richtigen Eigenschaftsbezeichnung vergessen kann - der Code verliert an Übersichtlichkeit und Wartbarkeit.

Ich suche also eine Möglichkeit, wie ich die bisherige Struktur beibehalten kann, und sie um ein Array zu erweitern, sodass aber in den einzelnen Zellen des Arrays dieselben Infos stecken wie in den einzelnen Eigenschaften. Also so, dass ich MyAudioFile.Artist im Code völlig synonym zu MyAudioFile.EigenschaftenArray[CONST_ARTIST] verwenden kann. Dabei muss als Index auch eine Variable entsprechenden Wertes möglich sein - z.B.: MyAudioFile.EigenschaftenArray[SortierPrioritätenArray[1]] Eine simple Ersetzung vor dem Kompilieren ist also nicht möglich.
  Mit Zitat antworten Zitat
Benutzerbild von Flocke
Flocke

Registriert seit: 9. Jun 2005
Ort: Unna
1.172 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#2

Re: Synonyme Bezeichnungen für eine Objekt-Eigenschaft

  Alt 27. Jul 2006, 17:37
Dazu bietet Delphi die Möglichkeit der Indizierung von Eigenschaften.

Beispiel:
Delphi-Quellcode:
type
  TMyClassStringIndex = (siName, siAlbum, siTitel);

  TMyClass = class(TObject)
  private
    FStrings: array [TMyClassStringIndex] of string;
    function GetString(Index: TMyClassStringIndex): string;
    procedure SetString(Index: TMyClassStringIndex; const Value: string);
  protected
    property Strings[Index: TMyClassStringIndex] read GetString write SetString;
  public
    property Name: string Index siName read GetString write SetString;
    property Album: string Index siAlbum read GetString write SetString;
    // usw...
  end;
Dann kannst du intern auf ein Array zugreifen.
Volker
Besucht meine Garage
Aktuell: RtfLabel 1.3d, PrintToFile 1.4
  Mit Zitat antworten Zitat
Benutzerbild von DGL-luke
DGL-luke

Registriert seit: 1. Apr 2005
Ort: Bad Tölz
4.149 Beiträge
 
Delphi 2006 Professional
 
#3

Re: Synonyme Bezeichnungen für eine Objekt-Eigenschaft

  Alt 27. Jul 2006, 17:37
property Artist: string read Props[cARTIST] write Props[cARTIST]; falls er da meckert musst du dir halt getter und setter bauen.

Delphi-Quellcode:
public
  procedure SetArtist(value: string);
  function GetArtist: string;
published
  property Artist: string read GetArtist write SetArtist;
//Ja, genau so....
Lukas Erlacher
Suche Grafiktablett. Spenden/Gebrauchtangebote willkommen.
Gotteskrieger gesucht!
For it is the chief characteristic of the religion of science that it works. - Isaac Asimov, Foundation I, Buch 1
  Mit Zitat antworten Zitat
Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#4

Re: Synonyme Bezeichnungen für eine Objekt-Eigenschaft

  Alt 27. Jul 2006, 18:15
Hi,
warum genau verwirfst du denn die Idee mit dem mehrfachen Sortieren? Ich denke die ist gar nicht so der schlechte Ansatz. Du brauchst natürlich weiterhin verschiedene Compare-Methoden (je nach Datentyp), aber für dieses Beispiel wolltest du dich ja auf Strings einschränken.
Also wenn du eine Liste von Objekten nach dem ersten Kriterium sortierst, schaffst du dies in O(n*log(n)) (im Mittel falls du Quicksort verwendest).
Gehst du diese Liste durch, benötigst du dafür O(n) Zeit, was durch das Sortieren dominiert wird. Suchst du nun hier die Gruppen, die gleich sind und sortierst diese erneut, hättest du maximal O(n*log(n)). Wenn du also nach der Effizienz gehst, ist mehrfaches Sortieren assymptotisch nicht Rechenzeitaufwändiger als einfaches Sortieren.

Allerdings kannst du hier noch einiges verbessern. Eine einfache Möglichkeit ist es, dass du Elemente, die den gleichen Wert (nach dem aktuellen Suchkriterium) besitzen in ein Array packst. Genau genommen kannst du sogar in-place arbeiten. Du hast dein zu sortierendes Array und speicherst einfach den Index der Teilfelder die nach dem aktuellen Kriterium gleiche Elemente enthalten.
Nun ist dein Feld bis auf diese Elemente schon sortiert. Das heißt, du brauchst nach dem nächsten Suchkriterium nur noch diese Felder sortieren. Dies sollte im Mittel deutlich schneller gehen. Einerseits fallen in jeder Iteration weitere Objekte raus, die schon sortiert sind und andererseit entstehen (wahrscheinlich) kleine Partionen, diese lassen sich dann deutlich schneller sortieren.
Zudem brauchst du weiterhin nur paarweise zu vergleichen.

Am meisten dürftest du allerdings davon profitieren, wenn du gleich sortiert einfügst. Wenn du ein Objekt bekommst, könntest du jede seiner Eigenschaften in je eine Liste (die dann konsistent gehalten werden müsste) sortiert einfügen. Sollte es dann zu einer Abfrage kommen, Liegt die Sortierung nach dem Kriterium schon vor. Bei einfügen sollte es in der Regel wenig Zeit kosten (sehen wir mal vom ersten hinzufügen eines Archivs ab), danach kommen doch eher geringe Mengen hinzu. Jeder Eintrag in einer solchen Liste kann dann noch einen Verweis auf das eigentliche Objekt enthalten (also ein Tupel aus dieser einen Eigenschaft nach der die Liste sortiert ist + Verweis auf das eigentliche Objekt).
Die ist allerdings ohne Frage keine speicher schonende Variante, da die Verweise sehr redundant abgelegt werden. Es muss aber eine solche Liste auch nicht für jedes Kriterium angelegt werden. Sicherlich macht es für Dinge, nach denen eher selten sortiert wird, bzw. die mit hoher Wahrscheinlichkeit gleich sind (z.B. SampleRate, Stimmung, ...) weniger Sinn eine solche Liste zu verwalten. Sollten diese Kriterien verwendet werden, muss halt vorher klassisch sortiert werden.

Nun alles zusammen:
Beim einfügen von neuen Daten, die wichtigen Eigenschaften sortiert ablegen (mit einem Verweis auf dieses neue Datum).
Wird nach mehreren Kriterien sortiert, so wird das Array zuerst nach dem primären Kriterium sortiert (sollte es eine Eigenschaft sein, zu der schon eine Sortierte Liste gehört, braucht man hier nichts zu tun und kann diese abrufen). In dieser Sortierung alle gleichen Elemente jeweils analog nach dem zweiten Kriterium sortieren (bis alles sortiert oder keine weiteren Kriterien vorhanden).

Gruß Der Unwissende
  Mit Zitat antworten Zitat
Benutzerbild von Gausi
Gausi

Registriert seit: 17. Jul 2005
877 Beiträge
 
Delphi 11 Alexandria
 
#5

Re: Synonyme Bezeichnungen für eine Objekt-Eigenschaft

  Alt 27. Jul 2006, 18:58
Es ist ja nicht das sortieren alleine. Dazu verwende ich auch die mitgelieferte Sort-Funktion der TObjectlist, wodurch sich das Sortieren auf kleine Mini-Funktionen (eben die Compare-Funktionen) beschränkt. Wenn ich den Code jetzt dahingehend erweitere, und Teile neu sortiere, ist das viel Coding-Aufwand.
Hinzu kommt, dass ich für die entsprechend sortierten Listen auch jeweils eine Binärsuche nach der sortierten Eigenschaft programmiert habe, und bei einem Treffer z.B. alle Objekte ausgebe, die die primäre Eigenschaft besitzen, oder aber die primäre UND sekundäre - da käme dann auch entsprechend Aufwand auf mich zu.

Ich brauche dieses variable Verfahren für folgendes:
  • Objekt-Liste sortieren nach variablen Kriterien
  • Weitere Liste erstellen, die eine Auflistung aller unterschiedlichen primären Eigenschaften hat (also z.B. Alle Interpreten)
  • bei Markierung eines Interpreten (z.B. Die Ärzte) (später auch Genre, Jahr, u.a.) erstens eine Auflistung aller unterschiedlichen sekundären Eigenschaften, die bei Objekten mit der gewählten primären Eigenschaft existieren (also alle Alben von den Ärzten, oder alle Künstler des Genres) UND eine Auflistung aller Objekte mit der gewählten primären Eigenschaft
  • Bei zusätzlicher Markierung einer sekundären Eigenschaft weitere Filterung der Objektanzeige, so dass nur Objekte angezeigt werden, die beide Eigenschaften haben (Z.B. Alle Titel von den Ärzten auf dem Album 13, oder alle Punkrock-Titel aus dem Jahr 2006)
Damit das in Echtzeit auch bei längeren Listen funktioniert, brauche ich eine Sortierung nach beiden Kriterien, und eine entsprechende Binärsuche...

Das Stichwort, was ich benötigte, war Getter/Setter . Ich hätte natürlich zuerst für jede Eigenschaft nen eigenen Setter/Getter geschrieben, aber wenn das auch in einem geht, ist das natürlich ne feine Sache

Ist doch richtig, dass die Getter-Methode einfach den Index-ten String aus dem Array zurückliefert, und der Setter einfach den String im Array neu setzt, oder? Also einfach
Delphi-Quellcode:
function GetString(Index: TMyClassStringIndex): String;
begin
  result := FStrings[Index];
end;

procedure SetString(Index: TMyClassStringIndex; const Value: string);
begin
  FStrings[Index] := Value;
end;
Jetzt muss ich zwar die Klasse etwas umbauen (das sind bis jetzt alles einfach nur Variablen, keine Propertys), aber der Rest des Projektes kann so bleiben.
  Mit Zitat antworten Zitat
Benutzerbild von Flocke
Flocke

Registriert seit: 9. Jun 2005
Ort: Unna
1.172 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#6

Re: Synonyme Bezeichnungen für eine Objekt-Eigenschaft

  Alt 27. Jul 2006, 19:06
Zitat von Gausi:
Ist doch richtig, dass die Getter-Methode einfach den Index-ten String aus dem Array zurückliefert, und der Setter einfach den String im Array neu setzt, oder? Also einfach
Delphi-Quellcode:
function GetString(Index: TMyClassStringIndex): String;
begin
  result := FStrings[Index];
end;

procedure SetString(Index: TMyClassStringIndex; const Value: string);
begin
  FStrings[Index] := Value;
end;
Ja - so einfach ist das.
Volker
Besucht meine Garage
Aktuell: RtfLabel 1.3d, PrintToFile 1.4
  Mit Zitat antworten Zitat
Benutzerbild von Gausi
Gausi

Registriert seit: 17. Jul 2005
877 Beiträge
 
Delphi 11 Alexandria
 
#7

Re: Synonyme Bezeichnungen für eine Objekt-Eigenschaft

  Alt 17. Aug 2006, 20:25
Danke nochmal dafür. Bin jetzt endlich dazu gekommen, das auch tatsächlich zu implementieren, und es läuft wunderbar. Nur eine Kleinigkeit für die Nachwelt:

Statt  property Strings[Index: TMyClassStringIndex] read GetString write SetString; muss es natürlich heißenproperty Strings[Index: TMyClassStringIndex]: String read GetString write SetString;
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:55 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz