代码之家  ›  专栏  ›  技术社区  ›  Triber A. I. Breveleri

如何比较枚举类型集

  •  8
  • Triber A. I. Breveleri  · 技术社区  · 6 年前

    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 回复  |  直到 6 年前
        1
  •  15
  •   David Heffernan    6 年前

    这个 set operators 帮助您实现这些功能

    为了 ContainsOne 我们使用 *

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

    为了 ContainsAll 我们会用 <= 它是子集运算符。

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

    这个 documentation 提供可用集合运算符的完整列表。

        2
  •  5
  •   MBo    6 年前

    你可以用 set intersection operator

    为了 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');