Как сравнить наборы перечислимых типов - PullRequest
0 голосов
/ 19 сентября 2018

С определенного момента я устал от написания заданных условий (and, or), потому что для большего количества условий или длинных имен переменных это становится неуклюжим и раздражает, когда приходится писать заново.Поэтому я начал писать помощников, чтобы я мог писать ASet.ContainsOne([ceValue1, ceValue2]) вместо (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;

К сожалению, это не самое эффективное решение, и оно противоречит принципу СУХОЙ.К моему удивлению, я не нашел никого, кто бы имел дело с той же проблемой, так что мне интересно, есть ли лучшее (универсальное) решение?

Ответы [ 2 ]

0 голосов
/ 19 сентября 2018

операторы множеств помогают вам реализовать эти функции

Для ContainsOne мы используем оператор *, который является оператором пересечения множеств.

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

Для ContainsAll мы будем использовать <=, который является оператором подмножества.

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

Учитывая простоту этих выражений, я задаюсь вопросом, нужен ли вам вспомогательный тип вообще.

Документация содержит полный список доступных операторов множеств.

0 голосов
/ 19 сентября 2018

Вы можете использовать оператор пересечения множества

Для ContainsOne аналоговой проверки, если пересечение не пустое множество, для ContainsAll проверки того, что пересечение совпадает с набором аргументов

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');
...