2007. november 9., péntek

Using Case structure with strings

Problem/Question/Abstract:

I am sure every one at some time has wanted to use a case structure with strings but that is not possible with delphi case structures. So this is my solution which I have used over and over...

Answer:

I created a function called string index that returns the index of a string within an array of strings.  The function returns -1 if the string was not found and is not case sensitive.

Usage:

Simply use like this

case StringIndex('Edit', ['Post', 'Edit', 'Cancel']) of
0: ; // Do somthing for Post "command"
1: ; // Do somthing for Edit "command"
2: ; // Do somthing for Cancel "command"
end;
{. }
{. }
{. }
or

if StringIndex('Edit', ['a', 'ab', 'rth']) = -1 then
// something
else
// something

StringIndex returns -1 if the string does not exist. This function is not case sensitive.

Of course the first string 'Edit' would be some variable.

Happy Coding!

Source:

unit Fn_StringIndex;

interface
uses
SysUtils;

function StringIndex(const SearchString: string; StrList: array of string): Integer;

implementation

function StringIndex(const SearchString: string; StrList: array of string): Integer;
var
I: Integer;
begin
Result := -1;
for I := 0 to High(StrList) do
if CompareText(SearchString, StrList[I]) = 0 then
begin
Result := I;
Break;
end;
end;

end.

SOME EXAMPLES OF USAGE

I decided it would be good for me to show all the places where I have used this function, so it is clearer the purpose I made it.

These are cuts directly from live code.

I hope this helps and maybe spark some ideas.

In this case I used it to determine my action if the OrdProp was Boolean or WordBool

EnumVal := GetOrdProp(Instance, PropInfo);
if StringIndex(PropInfo^.PropType^^.Name, ['Boolean', 'WordBool']) <> -1 then
begin
{ ... }
// to much to explain here
{ ... }
end
else
{ ... }

Here I am determining what kind of text to return based on the float type name

tkFloat: case StringIndex(Info.PropInfo^.PropType^^.Name,
['Currency', 'TDateTime']) of
0:
begin
Result := CurrToStr(GetFloatProp(Instance, PropInfo));
end;
1: Result := DateTimeToStr(GetFloatProp(Instance, PropInfo));
else
Result := FloatToStr(GetFloatProp(Instance, PropInfo));
end;

This converts a text string S to a boolean value.

function TRTTIModifier.TextToBool(S: string): Boolean;
begin
Result := StringIndex(S, ['', 'F', 'False', '0', 'No']) = -1;
end;

Taken from a web server application, to replace the passed tag "TagString" with whatever its suppose to.  This I think would be a must for anyone using borlands web server architech.

procedure TSite.StateHTMLTag(Sender: TObject; Tag: TTag;
const TagString: string; TagParams: TStrings; var ReplaceText: string);
begin
case StringIndex(TagString,
['UserID', 'UserCreationDate', 'UserSiteAccessTime', 'APPCreationDate',
'UserList', 'Host'])
of
0: ReplaceText := IntToStr(User.ID);
1: ReplaceText := DateTimeToStr(User.CreationDateTime);
2: ReplaceText := DateTimeToStr(User.LastUserAccess);
3: ReplaceText := DateTimeToStr(App.CreationDateTime) + ' RefCount=' +
IntToStr(App.ReferenceCount);
4: ReplaceText := 'User List has been disabled';
5: ReplaceText := App.Host;
end;
end;

Another snip from a web server app where the command was passed on the url. I am only giving a small snip of it, but I think you get the idea.

else
case StringIndex(Command,
['EDITOBJECT', 'MODIFY', 'GENFORM', 'DELETE',
'PREVIEW', 'EDIT', 'CREATESITE', 'Reload',
'CreateSubSite', 'LogOut', 'HistoryBack', 'HistoryForward',
'PublishSite', 'Copy']) of
0:
begin
Response.Content := EditObject(PassedObject, SubCommand);
end;
1:
begin

This is taken from a some laser controler software I wrote.... You can see that I am determining what method to call based on the file extension.

procedure TBoneEditorData.LoadAnyFile(const FileName: string);
var
Ext: string;
begin
Ext := ExtractFileExt(FileName);
case StringIndex(Ext, ['.fmc', '.ild', '.fbz', '.fgp', '.fif']) of
0: LoadMotionFile(FileName);
1: LoadIldaFile(FileName);
2: LoadBonesFile(FileName);
3: LoadCombo(FileName);
4: LoadImageFile(FileName);
else
raise Exception.CreateFmt('Cannot load files of this type extension "%s"', [Ext]);
end;
end;

This takes a code from a database field and converts it to an ord type

function TMDBSchedule.GetFrequency: TFrequency;
const
FreqArray: array[0..4] of string = ('Y', 'M', 'W', 'D', 'N');
var
FreqInput: string;
FreqOrd: integer;

begin
FreqInput := UpperCase(DataSet.FieldByName('Frequency').AsString);

FreqOrd := StringIndex(FreqInput, FreqArray);

case FreqOrd of
0: Result := frYearly;
1: Result := frMonthly;
2: Result := frWeekly;
3: Result := frDaily;
4: Result := frNone;
else
Result := frNone;
end;
end;

Thats all the most important stuff.... have fun!


Component Download: http://www.baltsoft.com/files/dkb/attachment/fn_stringindex.ziphttp://www.baltsoft.com/files/dkb/attachment/fn_stringindex.zip

Nincsenek megjegyzések:

Megjegyzés küldése