您熟悉此块:
Var
mySet: Set Of Char;
C: Char;
begin
mySet := ['a', 'b', 'c'];
If C In mySet Then ShowMessage('Exists');
end;
有没有办法申报Set Of STRING
?或者是否有类似的代码我可以使用?这个块的重要部分是If C In mySet Then ShowMessage('Exists');
我想在一组字符串中使用这样的东西
感谢。
答案 0 :(得分:11)
使用位数组实现集合。所以不,你不能拥有一套'字符串'。请改用TStringList,即:
var
mySet: TStringList;
S: String;
begin
S := ...;
mySet := TStringList.Create;
try
mySet.Add('a');
mySet.Add('b');
mySet.Add('c');
if mySet.IndexOf(S) <> -1 Then ShowMessage('Exists');
finally
mySet.Free;
end;
end;
答案 1 :(得分:9)
你可以利用这个。
type
TAnyEnum = (aeVal1, aeVal2, aeVal3);
TEnuns = set of TAnyEnum;
TAnyMessages: array [TAnyEnum] of String;
const
MyMessages: TAnyMessages = ('Exists', 'Something else', 'WTF!?');
var
MySet : TEnums;
begin
MySet = [aeVal1, aeVal2];
If aeVal1 in MySet then ShowMessage(MyMessages[aeVal1]);
end;
答案 2 :(得分:5)
RTL System.StrUtils
单元为此提供了一种非常有趣的方法:
function MatchText(const AText: string; const AValues: array of string): Boolean; overload;
像这样使用它:
if MatchText(sLanguages, ['fr-FR', 'en-GB', 'de-DE', 'it-IT', 'fr-CH', 'es-ES']) then
Writeln('found')
答案 3 :(得分:3)
很遗憾,但是Delphi仍然没有非常基本的数据结构,比如集合。 “Fabricio Araujo”的建议在使用上非常有限 - 你必须知道所有可能的字符串,所以当你从某个地方读取它们时它是无用的。在这样的“几乎一组字符串”中也不可能有超过256个项目。 Remy Lebeau建议使用TStringList来实现这个目的,但是当你拥有大集合时它绝对是低效的。在现代版本的Delphi中,可以使用TDictionary来保存任何无序的东西,包括字符串:
procedure TForm6.FormCreate(Sender: TObject);
type
TEmpty = record end;
var
MySet: TDictionary<String, TEmpty>;
Dummy: TEmpty;
begin
MySet := TDictionary<String, TEmpty>.Create;
try
MySet.Add('Str1', Dummy);
MySet.Add('Str2', Dummy);
MySet.Add('Str3', Dummy);
if MySet.TryGetValue('Str2', Dummy) then
ShowMessage('Exists');;
finally
MySet.Free;
end;
end;
区分大小写。如果你需要不区分大小写的实现,你可以在put / look然后在set中使所有字符串小写(使用AnsiLowerCase函数)。
答案 4 :(得分:1)
Fabricio Araujo发布了原始问题的最佳答案。
但是如果你问这个问题,你也应该问自己
“我仅是否需要知道Str是否在此集合中?”。
关于“月份名称的允许缩写集中是否有MonthAbbr?”的问题
您的下一个问题是“那么,是哪个月份?”。
因此您的代码可能显示为
case GetMonthNumber(Str) of
0: //Error: Str is not a Month Name or Abbreviation
1: //etc.
对于该实现,最简单的一般答案是在Delphi 7中使用排序的TStringList(因为标记了问题)。
答案 5 :(得分:0)
function MatchStr (常量AText:字符串;常量AValues:字符串数组):布尔值;超载;
MatchStr使用区分大小写比较确定数组AValues中的任何字符串是否与AText指定的字符串匹配。如果数组中的至少一个字符串匹配,则返回true;如果没有字符串匹配,则返回false。
对于不区分大小写的匹配,请使用 MatchText 例程。
答案 6 :(得分:0)
另一种选择是声明一个新的“String”类型并使用 RECORD HELPER 在其上实现“IN”运算符:
USES System.SysUtils, System.StrUtils;
TYPE
TextString = RECORD
PRIVATE
STR : STRING;
PUBLIC
CLASS OPERATOR Implicit(CONST S : STRING) : TextString; INLINE;
CLASS OPERATOR Implicit(CONST S : TextString) : STRING; INLINE;
END;
{ TextString }
CLASS OPERATOR TextString.Implicit(CONST S : STRING) : TextString;
BEGIN
Result.STR:=S
END;
CLASS OPERATOR TextString.Implicit(CONST S : TextString) : STRING;
BEGIN
Result:=S.STR
END;
TYPE
TStringHelper = RECORD HELPER FOR TextString
CLASS OPERATOR In(CONST T : TextString ; CONST ARR : ARRAY OF STRING) : BOOLEAN;
FUNCTION IsEmpty : BOOLEAN;
END;
{ TStringHelper }
CLASS OPERATOR TStringHelper.In(CONST T : TextString ; CONST ARR : ARRAY OF STRING) : BOOLEAN;
BEGIN
Result:=MatchText(T.STR,ARR)
END;
FUNCTION TStringHelper.IsEmpty : BOOLEAN;
BEGIN
Result:=STR.IsEmpty
END;
VAR
S : TextString;
T : STRING;
begin
try
REPEAT
WRITE('Enter an animal name: '); READLN(T); S:=T;
IF S.IsEmpty THEN EXIT;
IF S IN ['Bird','Lion','Monkey'] THEN WRITELN('You got it!') ELSE WRITELN('Nope - Try Again...')
UNTIL FALSE
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
它与赋值和比较中的 STRING 类型隐式兼容。它在“IN”运算符中隐式不区分大小写,并且通过扩展记录助手(使用 Equal/NotEqual/GreaterThan/LessThan/GreaterThanOrEqual/LessThanOrEqual 运算符到 STRING 和 TextString 类型),您可以制作完全不区分大小写的字符串类型。
缺点:您不能在 VAR/OUT STRING 参数中使用这种新类型,并且由于它的来回转换和比较中的大写字母,它比标准 STRING 类型慢一点。