我的状态存储为文件或数据库中设定长度的字符串。
我想要列举可能的状态'
我有以下类型来定义可能的状态'
Type TStatus = (fsNormal = Ord('N'),fsEditedOnScreen = Ord('O'),
fsMissing = Ord('M'),fsEstimated = Ord('E'),fsSuspect = Ord('s'),
fsSuspectFromOnScreen = Ord('o'),fsSuspectMissing = Ord('m'),
fsSuspectEstimated = Ord('e'));
首先这是一个好主意吗?或者我应该有一个单独的const数组存储char转换?这意味着不止一个地方需要更新。
现在将字符串转换为状态数组我有以下内容,但是如何在不循环枚举的情况下检查char是否有效?
Function StrToStatus(Value : String):TStatusArray;
var
i: Integer;
begin
if Trim(Value) = '' then
begin
SetLength(Result,0);
Exit;
end;
SetLength(Result,Length(Value));
for i := 1 to Length(Value) do
begin
Result[i] := TStatus(Value[i]); // I don't think this line is safe.
end;
end;
经过一些测试,同样可疑线路是安全的(它不会崩溃!)但只是添加(超出界限)值,然后需要过滤掉。
Function StrToStatus(Value : String):TStatusArray;
var
i: Integer;
begin
if Trim(Value) = '' then
begin
SetLength(Result,0);
Exit;
end;
SetLength(Result,Length(Value));
for i := 1 to Length(Value) do
begin
Result[i-1] := TStatus(Value[i]);
end;
for i := 0 to Length(Result) - 1 do
begin
case Result[i] of
fsNormal: ;
fsEditedOnScreen: ;
fsMissing: ;
fsEstimated: ;
fsSuspect: ;
fsSuspectFromOnScreen: ;
fsSuspectMissing: ;
fsSuspectEstimated: ;
else
Result [i] := fsNormal;
end;
end;
end;
这允许所有状态'及其相对Char值在一个位置,并防止循环遍历字符串中每个字符的每个状态。 (所以在我的脑海中至少应该快一点)
AFAIK这可以很好地再次转换回来。
Function StatusToStr(Value : TStatusArray):String;
var
i: Integer;
begin
for i := 0 to Length(Value) - 1 do
Result := Result + Chr(Ord(Value[i]))
end;
我正在使用Delphi 2007
答案 0 :(得分:2)
如果我理解正确的话,我会用一个集合替换数组,并使用没有显式值的枚举,如下所示:
program Project1;
{$APPTYPE CONSOLE}
uses
SysUtils;
type
TStatus = (fsNormal, fsEditedOnScreen, fsMissing, fsEstimated, fsSuspect,
fsSuspectFromOnScreen, fsSuspectMissing, fsSuspectEstimated);
TStatusSet = set of TStatus;
const
cStatusChars: array[TStatus] of Char = ('N', 'O', 'M', 'E', 's', 'o', 'm', 'e');
function CharToStatus(AChar: Char; out AStatus: TStatus): Boolean;
var
st: TStatus;
begin
for st := Low(TStatus) to High(TStatus) do
if cStatusChars[st] = AChar then
begin
AStatus := st;
Result := True;
Exit;
end;
Result := False;
end;
function StrToStatus(const Value: string): TStatusSet;
var
i: Integer;
st: TStatus;
begin
Result := [];
for i := 1 to Length(Value) do
if CharToStatus(Value[i], st) then
Include(Result, st);
end;
function StatusToStr(const Value: TStatusSet): string;
var
st: TStatus;
begin
for st in Value do
Result := Result + cStatusChars[st];
end;
var
StatusSet: TStatusSet;
begin
StatusSet := StrToStatus('EmO');
Writeln(StatusToStr(StatusSet));
Readln;
end.
答案 1 :(得分:0)
首先,我想知道为什么要将它保存为字符串而不是整数。
你做到了这一点,正确做到这一点的唯一方法就是拥有一个案例条件......
function CharToStatus(AChar : Char):TStatus;
begin
case AChar of
'N' : Result := fsNormal;
'O' : Result := fsEditedOnScreen;
'M' : Result := fsMissing;
'E' : Result := fsEstimated;
's' : Result := fsSuspect;
'o' : Result := fsSuspectFromOnScreen;
'm' : Result := fsSuspectMissing;
'e' : Result := fsSuspectEstimated;
else
//Manage error;
end;
end;
function StatusToChar(AStatus : TStatus) : char;
begin
Result := Char(AStatus);
end;
表达式x in [Low(TStatus)]..High(Tstatus)]
在这种情况下不起作用。
原因是Low(TStatus)='E'和High(TStatus)='s'。介于两者之间的任何内容都将被视为有效。 (即'Z'在[低(TStatus)] ..高(Tstatus)])
表达式x in [Low(TStatus)]..High(Tstatus)]
仅适用于声明中没有“漏洞”的类型。 (就像没有显式值的那些,第一个元素是0,第二个是1,第三个是2 ......等等)
// EDIT
好的..进一步思考问题,我不明白为什么你不喜欢const数组方法......这样的事情会好很多。
type
TStatus = (fsNormal, fsEditedOnScreen,
fsMissing,fsEstimated,fsSuspect,
fsSuspectFromOnScreen,fsSuspectMissing ,
fsSuspectEstimated);
const
StatusValue : Array[TStatus] of Char = ('N','O','M','E','s','o','m','e');
function StatusValueToTStatus(C : Char) : TStatus;
var I : Integer;
begin
for I := Low(StatusValue) to High(StatusValue) do
begin
if StatusValue = C then
begin
Result := TStatus(I);
EXIT;
end;
end;
//Not found, Manage errors
end;