我有几个硬编码的验证,如下所示:
const
cLstAct = 1;
cLstOrg = 4;
cLstClockAct = 11;
const
FUNCT_1 = 224;
FUNCT_2 = 127;
FUNCT_3 = 3;
if lFuncID in [FUNCT_1,FUNCT_2,FUNCT_3] then ...
if not (lListType in [cLstAct..cLstOrg,cLstClockAct]) then ...
if not (lPurpose in [0..2]) then ...
我想用一个通用的方法来代替
function ValidateInSet(AIntValue: integer; AIntSet: @@@): Boolean;
begin
Result := (AIntValue in AIntSet);
if not Result then ...
end;
但是对于AIntSet
,应该选择什么类型呢?
目前,整个代码中要测试的值达到了常量值232(因此,我可以使用TByteSet = Set of Byte),但我可以预见,当常量值超过255时,我们将遇到E1012 Constant expression violates subrange bounds
。
我的谷歌搜索失败了。
(目前在 Delphi 西雅图更新1)
5条答案
按热度按时间0yg35tkg1#
使用字典
TDictionary<Integer, Integer>
。值是无关紧要的,你只关心键。如果字典包含一个特定的键,那么这个键就是集合的成员。使用AddOrSetValue
添加成员,使用Remove
删除成员,使用ContainsKey
测试成员资格。使用字典的意义在于它提供了O(1)查找。
您不希望直接将此类型用作集。您应该将其 Package 在一个类中,该类只公开类似于集的功能。可以在此处找到这样的示例:https://stackoverflow.com/a/33530037/505088
h5qlskok2#
您可以使用
array of Integer
:jdzmm42g3#
如果您使用的是最近的 Delphi 版本,则可以使用
TArray<Integer>
。调用仅仅与使用集合相同(范围除外):
wbgh16ku4#
直接答案是
TBits
类http://docwiki.embarcadero.com/Libraries/Seattle/en/System.Classes.TBits.Bits
注意:这只能从 Delphi XE 4开始使用,但必须使用-http://qc.embarcadero.com/wc/qcmain.aspx?d=108829
然而,对于你的“整数集”,在大多数膨胀的情况下,它将占用
2^31 / 8
字节的内存(因为整数的负值甚至不会被考虑),这将是很多...所以我希望你永远不会真的想要一个完整整数的集合。或者你应该投资稀疏数组代替。或者更确切地说
或者也许
http://docwiki.embarcadero.com/Libraries/Seattle/en/System.SysUtils.TFunc
现在-只是为了演示,在真实的的应用程序中,您将创建这些集和数组一次,并缓存很长时间(永远,或至少除非配置更改需要重建它们)。
ekqde3dh5#
总之,我知道人们已经很多年没有回答这个问题了,但是这里有一个使用 Delphi 泛型的新解决方案:-
要使用include类,则编写
if(TUtilityArray<integer>.Contains(some integer value, [value1, value2 etc.])) then ...
。此方法的另一个好处是它也适用于其他原语。