Comment comparer des ensembles de types énumérés

voix
7

D'un certain point je suis fatigué d'écrire des conditions définies ( and, or), parce que , pour des conditions plus ou noms de variables plus il commence à être maladroit et ennuyeux d'écrire tout recommencer. Alors j'ai commencé à écrire des aides pour que je puisse écrire au ASet.ContainsOne([ceValue1, ceValue2])lieu de (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;

Malheureusement, ce n'est pas la solution la plus efficace et il est contre le principe DRY. À ma grande surprise, je ne trouve jamais quelqu'un qui traite du même problème, alors je me demande s'il y a une meilleure solution (générique)?

Créé 19/09/2018 à 13:24
source utilisateur
Dans d'autres langues...                            


2 réponses

voix
14

Les opérateurs ensemblistes vous aider à mettre en œuvre ces fonctions

Pour ContainsOnenous utilisons l' *opérateur qui est l'opérateur d'intersection réglée.

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

Pour ContainsAllnous utilisons <=qui est l'opérateur de sous - ensemble.

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

Compte tenu de la simplicité de ces expressions sont, je me demande si oui ou non vous avez besoin du type d'aide du tout.

La documentation donne la liste complète des opérateurs set disponibles.

Créé 19/09/2018 à 13:42
source utilisateur

voix
4

Vous pouvez utiliser l' opérateur d'intersection de jeu

Pour ContainsOnevérifier analogique si l' intersection n'est pas ensemble vide, pour ContainsAllvérifier cette intersection coïncide avec l' ensemble des arguments

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');
Créé 19/09/2018 à 13:35
source utilisateur

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