Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to compare sets of enumerated types

From a certain point I got tired of writing set conditions (and, or), because for more conditions or longer variable names it begins to be clumsy and annoying to write all over again. So I started writing helpers so I could write ASet.ContainsOne([ceValue1, ceValue2]) instead of (ceValue1 in ASet) or (ceValue2 in ASet).

type
  TCustomEnum = (ceValue1, ceValue2, ceValue3);
  TCustomSet = set of TCustomEnum;
  TCustomSetHelper = record helper for TCustomSet 
    function ContainsOne(ASet: TCustomSet): Boolean;
    function ContainsAll(ASet: TCustomSet): Boolean;
  end;

implementation

function TCustomSetHelper.ContainsOne(ASet: TCustomSet): Boolean;
var
  lValue : TCustomEnum;
begin
  for lValue in ASet do
  begin
    if lValue in Self then
      Exit(True);
  end;
  Result := False;
end;

function TCustomSetHelper.ContainsAll(ASet: TCustomSet): Boolean;
var
  lValue : TCustomEnum;
begin
  Result := True;
  for lValue in ASet do
  begin
    if not (lValue in Self) then
      Exit(False);
  end;
end;

Unfortunately, this is not the most effective solution and it's against the DRY principle. To my surprise, I didn't find anyone ever dealing with the same problem, so I wonder if there is any better (generic) solution?

like image 699
Triber Avatar asked Sep 19 '18 13:09

Triber


People also ask

Can == be used on enum?

equals method uses == operator internally to check if two enum are equal. This means, You can compare Enum using both == and equals method.

Can you compare enum to string?

For comparing String to Enum type you should convert enum to string and then compare them. For that you can use toString() method or name() method. toString()- Returns the name of this enum constant, as contained in the declaration.

Can two different enums have the same value?

1. Two enum names can have same value. For example, in the following C program both 'Failed' and 'Freezed' have same value 0.

How to compare enum members in Java?

Comparing enum members in Java. Prerequisite : enum in Java, == vs equals. In Java, enum is a special Java type used to define collections of constants. More precisely, a Java enum type is a special kind of Java class. An enum can contain constants, methods etc. enum can be defined as a group of named constant.

What is enumerated-type-name in Python?

Syntax: enum enumerated-type-name {value1, value2, value3…..valueN}; enum keyword is used to declare enumerated types after that enumerated type name was written then under curly brackets possible values are defined. After defining Enumerated type variables are created.

What is an enumerator value?

These values are defined by the programmer at the time of declaring the enumerated type. When we assign a float value in a character value then compiler generates an error in the same way if we try to assign any other value to the enumerated data types the compiler generates an error. Enumerator types of values are also known as enumerators.

What is enumerated type in C?

Enumerated type (enumeration) is a user-defined data type which can be assigned some limited values. These values are defined by the programmer at the time of declaring the enumerated type.


Video Answer


2 Answers

The set operators help you implement these functions

For ContainsOne we use the * operator which is the set intersection operator.

function TCustomSetHelper.ContainsOne(ASet: TCustomSet): Boolean;
begin
  Result := ASet * Self <> [];
end;

For ContainsAll we would use <= which is the subset operator.

function TCustomSetHelper.ContainsAll(ASet: TCustomSet): Boolean;
begin
  Result := ASet <= Self;
end;

Given how simple these expressions are, I question whether or not you need the helper type at all.

The documentation gives the full list of available set operators.

like image 65
David Heffernan Avatar answered Oct 07 '22 23:10

David Heffernan


You can use the set intersection operator

For ContainsOne analog check if intersection is not empty set, for ContainsAll check that intersection coincides with argument set

type
  TCustomEnum = (ceValue1, ceValue2, ceValue3);
  TCustomSet = set of TCustomEnum;
var
  ASet: TCustomSet;
begin
  ASet := [ceValue1, ceValue3];

  if ([ceValue1, ceValue2] *  ASet) <> [] then
     Memo1.Lines.Add('Somebody here');

  if ([ceValue1, ceValue3] *  ASet) = [ceValue1, ceValue3] then
     Memo1.Lines.Add('All are in home');
like image 38
MBo Avatar answered Oct 07 '22 22:10

MBo