How do I find a specific record by field in an array of records
I know this is probably a basic question but here goes. I have a const array of records defined:
TDocumentKindInfo = record
Employee: integer;
First: string;
Last: string;
Title: string;
end;
const
CDocumentKindInfos: array[TDocumentKind] of TDocumentKindInfo = (
(Emplyee: 1; First: 'Bob'; Last: 'Fredricks'; Title: 'Manager'),
(Emplyee: 2; First: 'Bill'; Last: 'Evans'; Title: 'Cashier'),
(Emplyee: 3; First: 'Jill'; Last: 'Dunne'; Title: 'Stocker'),
...
how do I find the Employee name who is the manager. I looked aroun开发者_Go百科d and couldn't find anything that helped. I'm a beginner to delphi. Using delphi 7.
I'd normally write it like this:
function FindDocumentByTitle(const Title: string): TDocumentKind;
begin
for Result := low(Result) to high(Result) do
if SameText(Title, CDocumentKindInfos[Result].Title) then
exit;
raise EDocumentNotFound.CreateFmt('Document titled ''%s'' not found.', [Title]);
end;
The function raises an error if no item can be found. Pretty soon you'll be looking to wrap all this up in classes.
try this code
for I:= Low(CDocumentKindInfos) to high(CDocumentKindInfos) do
begin
if CDocumentKindInfos[I].Title = 'Manager' then
begin
ShowMessage('Employee name is ' + CDocumentKindInfos[I].Employee);
Break;
end;
end;
I realize the question is 3 years old, but thought I'd add to the answers.
When iterating through an array of records, I often code like this:
type TData = record
Points: Integer;
Count: Cardinal;
flags: Cardinal;
end;
PData = ^Data;
TDataArray = array of TData
PDataArray = ^TDataArray
...
var LongNameForSomeNouns: TDataArray
Noun: PData; //pointer to the current Record
iNoun: Integer;
...
for iNoun:=Low(LongNameForSomeNouns) to High(LongNameForSomeNouns) do begin
Noun := @LongNameForSomeNouns[iNoun];
Noun.Points := 5;
Inc(Noun.Count);
SomeFunction(Noun);
end;
Three points I'd like to make:
I seldom use i for an iterator. Too meaningless. Instead, I use i as a prefix (meaning iterator) to a short term that reminds me what is being iterated. This way some errors like 'SomeVerbs[iNoun]' become obvious.
Using an intermediate variable like Noun as a Record Pointer compacts my code without the evil that is 'With'. When you nest such loops, use separate iterators and Record Pointers.
Passing Record Pointers as parameters means Delphi will never make a copy of the Record. It also means the receiving function can modify the Record. If you want to pass a copy, you can do so explicitly.
Finally, why use Records instead of Objects? Performance. Following pointers to pointers causes cache-thrashing, which kills performance. An array of Objects is actually an array of pointers to Objects. Each layer of indirection forces the CPU to call a different line of memory into cache, which can stall the CPU. It's far worse than just having a fixed, small cache. Your CPU has a small number of cache lines.
Yes, that only matters for certain types of programs, and only after profiling. But I've gotten speed improvements of 50-100x by paying attention to things like that. One program that used to take a week to process 10M database records now finishes overnight. Where it used to be CPU bound it's now entirely Database IO bound.
精彩评论