AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Generic ObjectList und Suchen - Wie am besten ?

Ein Thema von OlafSt · begonnen am 6. Aug 2014 · letzter Beitrag vom 6. Aug 2014
Antwort Antwort
Seite 2 von 3     12 3      
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#11

AW: Generic ObjectList und Suchen - Wie am besten ?

  Alt 6. Aug 2014, 11:56
Warum erzeugst du dann nicht eine typisierte generische Objektliste?

Delphi-Quellcode:
  TMyObjectList<T> = class(System.Generics.Collections.TObjectList<TDriverBase>)
   public
      function Search(ASearchCrit: integer): T;
   end;
Und wie bekommst du jetzt die Einschränkung hin? Denn das geht ja jetzt auch:
Delphi-Quellcode:
var
  List : TMyObjectList<Integer>;
Oder wolltest du eher so etwas schreiben:
Delphi-Quellcode:
  TMyObjectList<T:TDriverBase> = class(System.Generics.Collections.TObjectList<T>)
   public
      function Search(ASearchCrit: integer): T;
   end;
Allerdings ist die Variante von Stevie doch genau richtig. Die kann ich für alle Varianten benutzen. Und wenn ich eine Liste benötige, in der sich nur Elemente vom Typ TDriverBase und davon abgeleitete Klassen, dann
Delphi-Quellcode:
var
  List : TMyObjectList<TDriverBase>;
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
OlafSt

Registriert seit: 2. Mär 2007
Ort: Hamburg
284 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#12

AW: Generic ObjectList und Suchen - Wie am besten ?

  Alt 6. Aug 2014, 13:07
Wie praktisch, das einem der Kaffee ausgeht und man schnell mal losmuß, neuen zu besorgen. Sind ja tolle Ideen hier aufgeführt, danke schonmal dafür.

TMyObjectList<T:TDriverBase> = class(System.Generics.Collections.TObjectList<T>) ist eigentlich das, was mir vorschwebt. Dann sorgt doch schon der Compiler dafür, das ich da keinen Integer oder TWorkTime (der nichts mit TDriverBase zu tun hat) versuche einzufügen. Ain't I right ?

Die Datenmengen halten sich da in engen Grenzen, ein paar hundert Items, schlimmstenfalls. Da geht ein linear search allemal, wirds zu dolle, weiche ich dann schon von selbst auf ein binary search aus. Das Risiko ist aber gering. Mir geht es eigentlich darum, das ich immer wieder und wieder dieselben Routinen bastele:
Delphi-Quellcode:
//Suche Fahrer (Basisklasse)
function FindDriverByID(AID: integer): TDriverBase;
begin
   for Result in self do
      if Result.ID = AID then exit;
   Result:=nil;
end;

function FindDriverByName(AName: string): TDriverBase;
begin
...
end;

//Suche Fahrer (SpezialKlasse)
function FindSpecialDriverByID(AID: integer): TSpecialDriver;
begin
   for Result in self do
      if Result.ID = AID then exit;
   Result:=nil;
end;

function FindSpecialDriverByName(AName: string): TSpecialDriver;
begin
...
end;

//Suche Arbeitszeiten
function FindWorkTimeByID(AID: integer): TWorkTime;
begin
   //Benutzt natürlich eine andere Collection mit Worktimes drin
   for Result in self do
      if Result.ID = AID then exit;
   Result:=nil;
end;

function FindWorkTimeByDate(ADate: TDateTime): TWorkTime;
begin
   for Result in self do
      if Result.WorkDate = ADate then exit;
   Result:=nil;
end;

//und so weiter und so fort...
Ich suche nun einen Weg, sowas eben nur ein einziges Mal machen zu müssen und ich dachte, Generics sind ein idealer Weg dafür. Während der Fahrt nachgedacht bin ich dann auf folgende - beinahe ideale - Lösung gekommen: Da meine Fahrer alle ein paar Gemeinsamkeitein haben (eine eindeutige ID, Namen etc) und eigentlich nur über diese Felder gesucht wird, stopfen wir das in die TDriverBase-Klasse. Anschließend nehmen wir die oben genannte Deklaration und basteln die Suchroutinen - und schon kann ich prima Listen für meine verschiedenen Fahrertypen erzeugen, in die ich nix "unsinniges" stecken kann und doch ohne duplizierten Code suchen und ggf. noch andere lustige Dinge anstellen:
Delphi-Quellcode:
TMyObjectList<T:TDriverBase> = class(System.Generics.Collections.TObjectList<T>)
public
  function FindByID(AID: integer): T;
  function FindByName(AName: string): T;
end;

var
  TDriverList: TMyObjectList<TDriver>;
  TSpecialDriverList: TMyObjectList<TSpecialDriver>;
  //15 Bier später...
  TWorkTimeList: TMyObjectList<TWorkTime>; //funzt nicht, gibt sofort Haue vom Compiler
Damit bin ich einen gewaltigen Haufen Suchroutinen schon mal los. Genial, danke für den Schubser an euch alle.
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

Registriert seit: 12. Aug 2003
Ort: Soest
4.016 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#13

AW: Generic ObjectList und Suchen - Wie am besten ?

  Alt 6. Aug 2014, 13:17
Ich suche nun einen Weg, sowas eben nur ein einziges Mal machen zu müssen und ich dachte, Generics sind ein idealer Weg dafür.
Die Ideallösung habe ich oben bereits geschrieben. Wenn du dir nämlich anschaust, wo sich deine ganzen Funktionen unterscheiden, siehst du, dass es immer das Suchkriterium ist. Und genau das kannst du mit einer Predicate lösen, du gibst nämlich dann in die Search Methode die anonyme Methode hinein, die das Kriterium auf dein Item anwendet und dir sagt, obs passt oder nicht.
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight
  Mit Zitat antworten Zitat
OlafSt

Registriert seit: 2. Mär 2007
Ort: Hamburg
284 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#14

AW: Generic ObjectList und Suchen - Wie am besten ?

  Alt 6. Aug 2014, 13:23
Okay, schlagendes Argument. Doch wo ist die Schleife, die durch alle Items iteriert ? Ich sehe da nur eine Vergleichsfunction - oder krieg ich da was nicht mit ?

[Edit]Ich bin ein Depp. Die Schleife mache ich selbst, ich Hirni
[Edit2] Sorry, ich kapiers doch nicht
[Edit3] Etwa so:
Delphi-Quellcode:
function TMyObjectList<T>.Find(const Predicate: TPredicate<T>): T;
begin
     for Result in self do
          if Predicate(T) then
             exit;
     Result:=nil;
end;

function TMyObjectList<T>.FindByID(AID: integer): T;
begin
     self.Find(function(Obj: TDriverBase): boolean begin Result:=Obj.DriverID = AID; end);
end;
Na, ob das wirklich funktioniert :-~

Geändert von OlafSt ( 6. Aug 2014 um 13:46 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

Registriert seit: 12. Aug 2003
Ort: Soest
4.016 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#15

AW: Generic ObjectList und Suchen - Wie am besten ?

  Alt 6. Aug 2014, 13:45
Delphi-Quellcode:
function TMyObjectList<T>.Search(const predicate: TPredicate<T>): T;
begin
  for Result in Self do
    if predicate(Result) then
      Exit;
end;
TPredicate<T> ist in SysUtils definitiert.
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight
  Mit Zitat antworten Zitat
Mikkey

Registriert seit: 5. Aug 2013
265 Beiträge
 
#16

AW: Generic ObjectList und Suchen - Wie am besten ?

  Alt 6. Aug 2014, 13:58
Wenn Du die Arbeit nur einmal machen willst, dann mache doch eine Anleihe bei den .NET-Klassen, bzw. bei der Art, wie solche Dinge dort geregelt werden.

Wenn Du eine Searchable-List erzeugen willst, dann nimmst Du nur Mitgliederklassen an, die ein Interface "IComparable" implementieren. So kannst Du ohne Wissen um die konkrete Klasse die Objekte in Deiner Klasse sortieren. Hast Du Deine Liste in sortierter Form, dann ist auch eine binäre Suche leicht zu implementieren.
  Mit Zitat antworten Zitat
OlafSt

Registriert seit: 2. Mär 2007
Ort: Hamburg
284 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#17

AW: Generic ObjectList und Suchen - Wie am besten ?

  Alt 6. Aug 2014, 13:59
Oh mann, wie genial ist das denn.
  Mit Zitat antworten Zitat
Benutzerbild von Union
Union

Registriert seit: 18. Mär 2004
Ort: Luxembourg
3.492 Beiträge
 
Delphi 7 Enterprise
 
#18

AW: Generic ObjectList und Suchen - Wie am besten ?

  Alt 6. Aug 2014, 14:10
Delphi-Quellcode:
function TMyObjectList<T>.Search(const predicate: TPredicate<T>): T;
begin
  for Result in Self do
    if predicate(Result) then
      Exit;
end;
TPredicate<T> ist in SysUtils definitiert.
In der Funktion fehlt noch eine Zeile:
Delphi-Quellcode:
function TMyObjectList<T>.Search(const predicate: TPredicate<T>): T;
begin
  for Result in Self do
    if predicate(Result) then
      Exit;
  Result := nil // <<< Das muß rein sonst ist jede Suche erfolgreich mit dem letzten Element!
end;
Ibi fas ubi proxima merces
sudo /Developer/Library/uninstall-devtools --mode=all
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

Registriert seit: 12. Aug 2003
Ort: Soest
4.016 Beiträge
 
Delphi 10.1 Berlin Enterprise
 
#19

AW: Generic ObjectList und Suchen - Wie am besten ?

  Alt 6. Aug 2014, 14:23
Delphi-Quellcode:
function TMyObjectList<T>.Search(const predicate: TPredicate<T>): T;
begin
  for Result in Self do
    if predicate(Result) then
      Exit;
end;
TPredicate<T> ist in SysUtils definitiert.
In der Funktion fehlt noch eine Zeile:
Delphi-Quellcode:
function TMyObjectList<T>.Search(const predicate: TPredicate<T>): T;
begin
  for Result in Self do
    if predicate(Result) then
      Exit;
  Result := nil // <<< Das muß rein sonst ist jede Suche erfolgreich mit dem letzten Element!
end;
Hasse recht, sofern kein constraint auf T liegt, muss es allerdings Result := Default(T); heißen.
Stefan
“Simplicity, carried to the extreme, becomes elegance.” Jon Franklin

Delphi Sorcery - DSharp - Spring4D - TestInsight
  Mit Zitat antworten Zitat
OlafSt

Registriert seit: 2. Mär 2007
Ort: Hamburg
284 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#20

AW: Generic ObjectList und Suchen - Wie am besten ?

  Alt 6. Aug 2014, 14:38
WTF ist ein constraint ? Irgendwie hab ich was verpaßt, glaub ich
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 3     12 3      


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 11:16 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