2011-03-11 130 views
2

我知道這可能是一個基本問題,但在這裏。 我有記錄的常量數組定義:我如何根據記錄數組中的字段找到特定的記錄

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'), 
... 

如何找到員工的名字誰是經理。我環顧四周,找不到任何有幫助的東西。我是德爾菲的初學者。用Delphi 7

回答

6

我通常把它寫這樣的:

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;  

的函數拋出一個錯誤,如果任何項目都可以找到。很快你就會想要把所有這些都包裝在課堂上。

+0

+ +1對於循環良好的循環結果作爲迭代索引 - 此類代碼快速且高效 - 唯一的缺點是您必須指定一些超出範圍的元素以指出錯誤。你可以使用const dkUnknown:TDocumentKind = TDocumentKind(255);創建一個「虛擬」TDocumentKind項目,如果找不到它就返回。 – 2011-03-11 17:15:55

+0

@ A.Bouchez在沒有明顯的未發現哨兵的情況下,我剛選擇加註。 – 2011-03-11 17:19:21

+0

我更喜歡引發異常。然後,您不必編寫9層以上的錯誤,然後退出代碼。 – 2011-03-11 20:00:00

2

試試這個代碼

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; 
+0

或'SameText(CDocumentKindInfos [I] .title僞,「經理」),'如果你想不區分大小寫 – 2011-03-11 14:50:13

+0

感謝,做它 - 鮑勃 – 2011-03-11 15:07:37

+2

你正在做的一個作業,如果,它不會編譯:) – jachguate 2011-03-11 16:41:15

0

我意識到問題是3歲,但認爲我會增加答案。

當通過一組記錄迭代,我經常這樣的代碼:

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; 

三點我想提出:

  1. 我很少用我的迭代器。太無意義了。相反,我使用i作爲前綴(意思是迭代器)來短時間提醒我什麼是迭代。這樣一些錯誤,如「SomeVerbs [iNoun]」變得明顯。

  2. 使用像Noun這樣的中間變量作爲記錄指針可以壓縮我的代碼,而不會使用'With'這個邪惡的東西。當你嵌套這樣的循環時,使用單獨的迭代器和記錄指針。

  3. 傳遞記錄指針作爲參數意味着德爾福永遠不會製作記錄的副本。這也意味着接收功能可以修改記錄。如果你想傳遞一份副本,你可以明確地做。

最後,爲什麼使用記錄而不是對象?性能。以下指針指向導致高速緩存抖動,從而導致性能下降。對象數組實際上是指向對象的指針數組。每一層間接強制CPU將不同的內存線調入高速緩存,這可能會使CPU停頓。這遠比只有一個固定的小緩存更糟糕。你的CPU有少量的緩存行。

是的,這隻對特定類型的程序很重要,並且只在分析之後。但通過關注這樣的事情,我已經獲得了50-100倍的速度提升。一個過去需要一週處理10M數據庫記錄的程序現在在一夜之間完成。它曾經被CPU綁定,現在它完全是數據庫IO綁定。

相關問題