Как сравнить наборы перечисляемых типов

голоса
7

С определенного момента я устал писать заданных условий ( 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;

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

Задан 19/09/2018 в 13:24
источник пользователем
На других языках...                            


2 ответов

голоса
14

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

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

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

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

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

Учитывая то, насколько просто эти выражения, я вопрос, нужен ли вам тип помощника вообще.

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

Ответил 19/09/2018 в 13:42
источник пользователем

голоса
4

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

Для 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');
Ответил 19/09/2018 в 13:35
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more