delphi - 如何比较枚举类型集
问题描述
从某一点开始,我厌倦了编写集合条件(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;
不幸的是,这不是最有效的解决方案,而且违反了 DRY 原则。令我惊讶的是,我没有发现任何人处理过同样的问题,所以我想知道是否有更好的(通用)解决方案?
解决方案
集合运算符帮助您实现这些功能
因为ContainsOne
我们使用的*
是集合交集运算符。
function TCustomSetHelper.ContainsOne(ASet: TCustomSet): Boolean;
begin
Result := ASet * Self <> [];
end;
因为ContainsAll
我们将使用<=
which 是子集运算符。
function TCustomSetHelper.ContainsAll(ASet: TCustomSet): Boolean;
begin
Result := ASet <= Self;
end;
鉴于这些表达式有多简单,我怀疑你是否需要辅助类型。
该文档提供了可用集合运算符的完整列表。
推荐阅读
- python - Python RegEx 寻找给定单词的组合(而不是排列):有可能吗?
- regex - 从 1 行字符串中选择北向
- python - 如何在 Python 中隐藏时间差金融股市图表?
- pandas - TypeError:“NoneType”对象在检查无类型时不可下标
- java - ReentrantLock 线程随机终止
- bash - 如何使用期望脚本在浏览器上打开网址?
- javascript - JSON 中位置 0 处的意外标记 #
- php - 在 PHP 中检测 413(或其他 HTTP 状态)
- react-native - React Drawer Navigation 菜单图标未显示
- javascript - 打字稿。在 tsconfig.json 中使用 ESNext 作为目标时如何防止转译?