Hvordan å sammenligne sett med oppregnet typer

stemmer
7

Fra et visst punkt jeg ble lei av å skrive set vilkår ( and, or), fordi for flere forhold eller lengre variabelnavnene det begynner å bli klumpete og irriterende å skrive på nytt. Så jeg begynte å skrive hjelpere slik at jeg kunne skrive ASet.ContainsOne([ceValue1, ceValue2])i stedet for (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;

Dessverre, dette er ikke den mest effektive løsningen og det er mot DRY-prinsippet. Til min overraskelse fant jeg ikke noen noensinne å gjøre med det samme problemet, så jeg lurer på om det er noe bedre (generisk) løsning?

Publisert på 19/09/2018 klokken 13:24
kilden bruker
På andre språk...                            


2 svar

stemmer
14

De faste operatører hjelpe deg med å implementere disse funksjonene

For ContainsOnevi bruker *operatøren som er sett kryss operatør.

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

For ContainsAllvi ville bruke <=som er undergruppe operatør.

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

Gitt hvor enkelt disse uttrykkene er, jeg spørsmålet om du trenger hjelpetype i det hele tatt.

Den dokumentasjonen gir en fullstendig liste over tilgjengelige faste operatører.

Svarte 19/09/2018 kl. 13:42
kilden bruker

stemmer
4

Du kan bruke settet krysset operatør

For ContainsOneanalog sjekke om skjæringspunktet ikke er tomme settet, for ContainsAllsjekk som skjæringspunktet sammenfaller med argument sett

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');
Svarte 19/09/2018 kl. 13:35
kilden bruker

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