Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Aufzählungstypen vereinigen (https://www.delphipraxis.net/167498-aufzaehlungstypen-vereinigen.html)

blablab 2. Apr 2012 14:02

Aufzählungstypen vereinigen
 
Hallo!

Ich möchte eine Aufzählung definieren, die aus mehreren anderen Aufzählungen besteht.
Delphi-Quellcode:
type
   TTeilmengeA = (a1, a2, a3);
   TTeilmengeB = (b1, b2, b3);
   TAll = TTeilmengeA + TTeilmengeB;
Da das leider nicht geht hab ich es so versucht:
Delphi-Quellcode:
type
   TAll = (a1, a2, a3, b1, b2, b3);
   TTeilmengeA = a1..a3;
   TTeilmengeB = b1..b3;
Am Schluss möchte ich dann eine Variable vom Typ TAll haben und überprüfen ob sie sich in der Teilmenge TTeilmengeA oder TTeilmengeB befindet. In etwa so:
Delphi-Quellcode:
var typ: TAll;
if typ in TeilmengeA then begin
...
Das einzige was mir dazu einfällt ist:
Delphi-Quellcode:
var typ: TAll;
if (typ >= Low(TTeilmengeA)) and (typ <= High(TTeilmengeA)) then begin ...
Gibt es hier noch eine bessere Lösung?

Grüße
blablab

uligerhardt 2. Apr 2012 14:09

AW: Aufzählungstypen vereinigen
 
Vielleicht so:
Delphi-Quellcode:
type
  TAll = (a1, a2, a3, b1, b2, b3);
const
  cTeilmengeA = [a1..a3];
  cTeilmengeB = [b1..b3];
var
  typ: TAll;

  if typ in cTeilmengeA then

Blup 3. Apr 2012 08:46

AW: Aufzählungstypen vereinigen
 
Der "in"-Operator ist nur für ein Element einer Menge definiert, nicht für Menge in Menge.
Delphi-Quellcode:
type
  Ta = (a1, a2, a3, a4, a5, a6);
  TaMenge = set of Ta;

function AinB(const A, B: TaMenge): Boolean;
begin
  Result := (a = (a * b));
end;

procedure TestMenge;
const
  a: TaMenge = [a1, a6];
  b1: TaMenge = [a1, a2, a4, a5];
  b2: TaMenge = [a2, a4, a6];
begin
  if AinB(a, b1 + b2) then
    {...}

uligerhardt 3. Apr 2012 08:56

AW: Aufzählungstypen vereinigen
 
Zitat:

Zitat von Blup (Beitrag 1159916)
Der "in"-Operator ist nur für ein Element einer Menge definiert, nicht für Menge in Menge.

Und Ersteres will der OP ja auch:
Zitat:

Zitat von blablab (Beitrag 1159853)
Am Schluss möchte ich dann eine Variable vom Typ TAll haben und überprüfen ob sie sich in der Teilmenge TTeilmengeA oder TTeilmengeB befindet. In etwa so:
Delphi-Quellcode:
var typ: TAll;
if typ in TeilmengeA then begin
...


himitsu 3. Apr 2012 09:26

AW: Aufzählungstypen vereinigen
 
OK, dann
IN ist nur für das Prüfen eines Elementes in einer Mengenvariable
und nicht in einem Mengentypen.

Man könnte Embarcadero im QS mal fragen, ob die das nicht implementieren könnten
oder man geht eben doch über die Konstanten.


Delphi-Quellcode:
type
   TAll = (a1, a2, a3, b1, b2, b3);
   TTeilmengeA = a1..a3;
   TTeilmengeB = b1..b3;

const
//cTeilmengeA = [a1..a3];
//cTeilmengeB = [b1..b3];
  cTeilmengeA = [Low(TTeilmengeA)..High(TTeilmengeA)];
  cTeilmengeB = [Low(TTeilmengeB)..High(TTeilmengeB)];

Man könnte sich auch sowas basteln
Delphi-Quellcode:
type
  MyHelper = class abstract
    class function IsInType<TEnum{: ENUM}>(const Value: TEnum): Boolean;
  end;
Schade daß es die Einschränkung enum/ordinal nicht gibt, dann wäre der Code darin voll einfach, ohne über die RTTI und einige Casts gehn zu müssen.

Iwo Asnet 3. Apr 2012 13:50

AW: Aufzählungstypen vereinigen
 
Interessant, konzeptionell unvereinbare Mengen (Enums) plötzlich über einen Kamm zu scheren und unter einen Hut packen zu wollen.

Ob da nicht ein Designfehler vorliegt? :gruebel:

himitsu 3. Apr 2012 14:49

AW: Aufzählungstypen vereinigen
 
Ach ja, warum das Zusammenfügen nicht geht, aber das Aufteilen schon, ist recht einfach erklärt.

Die Werte des Enums sind ja "nur" Namentliche Bezeichner für je einen bestimmten nummerischen Wert.
Ersetzt man mal die Namen durch ihre Werte, dann fällt das Dilemma auf.

Delphi-Quellcode:
type
   TTeilmengeA = (0, 1, 2);
   TTeilmengeB = (0, 1, 2);
   TAll = TTeilmengeA + TTeilmengeB; // würde nun doppeldeutige Werte enthalten ( ist die 0 nun A oder B? )

type
   TAll = (0, 1, 2, 3, 4, 5);
   TTeilmengeA = 0..2;
   TTeilmengeB = 3..5;

blablab 5. Apr 2012 10:22

AW: Aufzählungstypen vereinigen
 
Vielen Dank für eure Antworten!

Statt
Delphi-Quellcode:
if typ in [Low(TTeilmengeA)..High(TTeilmengeA)] then begin
   ...
end;
hab ichs jetzt so gemacht:
Delphi-Quellcode:
case typ of
   Low(TTeilmengeA)..High(TTeilmengeA): ...;
end;
Kommt ja im Prinzip aufs selbe hinaus, allerdings muss bei letzterem nicht extra ein "set of TAll" erstellt werden und ich vermute mal dass es deshalb schneller ist.

Also vielen Dank für eure Hilfe!

himitsu 5. Apr 2012 10:29

AW: Aufzählungstypen vereinigen
 
Dieses Set
Delphi-Quellcode:
[Low(TTeilmengeA)..High(TTeilmengeA)]
wird schon im Compiler erstellt, als implizite Konstante und dann wird darauf nur noch eine einzige Abfrage darauf ausgeführt.
Gut, in den x86-CPUs soll dieser eine BTC-Befehl nicht unbedingt der aller Schnellste sein, aber egal. (vom Code her ist das doch übersichtlicher? )

Beim CASE sind das mehrere Assemblerbefehle für die beiden Vergleiche und Delphi optimiert ein CASE sogar zu mehreren mathematischen Opperationen (meist 'ne Subtraktion) und einfachen Vergleichen mit 0.


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:01 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