2014-04-01 3 views
0

많은 레코드를 보유하고있는 배열이 있습니다. 다음과 같이 설정 :델파이/라자루스의 레코드 배열에 저장된 레코드 검색

Tcustomer= record 
    Name: string[40]; 
    Address: string[100]; 
    phone: string[15]; 
    email:string[50]; 
end; 

을 지금, 나는이 특정 이름 특정 주소를 가진 사람이 배열을 검색하고 싶었 말할 수 있습니다. 나는 이것에 대해 어떻게 갈 것인가? 그래서 기본적으로 하나 이상의 요소를 검색합니다. 첨부

의 사진입니다 (나는 1 개 이상 구체적으로 1 부동산하지만 캔트 필터를 검색 할 수 있습니다) 내 양식이 설정되어 내가 언급하고있는 무슨이에 관해서 더 자세히 보여주지 방법 :

enter image description here

+0

배열을 반복하여 일치하는 항목을 찾으십시오. 왜 고정 길이 문자열을 사용하는지 궁금합니다. –

+0

@DavidHeffernan thats 내 요점은, 루프 내에서 배열에서 1 개의 특정 것을 검색 할 때만 할 수 있습니다. 너는 어떻게 생각하고 있니? : S – user3478431

+0

궁극적으로 몇 가지 기준에 의해 일치를 검사하는 모든 요소를 ​​둘러싼 루프가 있습니다. 여러 경기를 찾으려면 할 수 있습니다. 특정 문제가있는 경우 알려주십시오. –

답변

3

루프를 반복하면서 배열의 여러 속성을 확인하면됩니다. 다음은 이름, 주소, 전화 또는 전자 메일 중 일치하는 항목을 검색하는 예제입니다. 여러 레코드 속성 (예 : 주소와 같은)에서 일치하는 항목을 찾으려면 테스트에서 or 절을 if (Customers[Idx].Name = Name) and (Customers[Idx].Address = Address) then과 같이 and을 사용하는 두 개 이상의 테스트로 바꿉니다.

type 
    TCustomer = record 
    Name: string[40]; 
    Address: string[100]; 
    Phone: string[15]; 
    Email:string[50]; 
    end; 

    TCustomerList: array of TCustomer; 

function FindCustomer(const Name, Address, EMail, 
    Phone: string; const Customers: TCustomerList): Integer; 
var 
    i: Integer; 
begin 
    Result := -1;       // Value if no match found 
    for i := Low(Customers) to High(Customers) do 
    begin 
    if (Customers[i].Name = Name) or  // Name matches? 
     (Customers[i].Address = Address) or // Address? 
     (Customers[i].EMail = EMail) or  // Same email? 
     (Customers[i].Phone = Phone) then // Same phone 
     begin 
     Result := i;      // Yep. We have a match. 
     Exit;        // We're done. 
     end; 
    end; 
end; 

샘플 사용 :

function FindCustomerByNameAndAddress(const Name, Address: string; 
    const Customers: TCustomerList): Integer; 
var 
    i: Integer; 
begin 
    Result := -1;       // Value if no match found 
    for i := Low(Customers) to High(Customers) do 
    begin 
    if (Customers[i].Name = Name) then   // Name matches. 
     if (Customers[i].Address = Address) then // Does address? 
     begin 
     Result := i;       // Yep. We found it 
     Exit;        
     end; 
    end; 
end; 

샘플 사용 :

var 
    Idx: Integer; 
begin 
    // Customers is your array of TCustomer in a TCustomerList 
    Idx := FindCustomer('', '', '', '[email protected]', Customers); 
    if (Idx = -1) then 
    WriteLn('No match found.') 
    else 
    WriteLn(Format('Customer %d: %s %s %s %s', 
        [Idx, 
        Customers[Idx].Name, 
        Customers[Idx].Address, 
        Customers[Idx].Phone, 
        Customers[Idx].EMail])); 
end; 

(예 : NameAddress 등) 값의 조합에 일치하려면, 그냥 적절하게 if의 조건을 변경 :

Idx := FindCustomerByNameAndAddress('John Smith', '123 Main Street`); 
if Idx = -1 then 
    // Not found 
else 
    // Found. Same code as above to access record. 
+0

왜 CompareMem과 레코드를 비교하지 않습니까? 'FindCustomer'는 정확한 일치를 반환하지 않습니다. – user3060326

+0

@ user3060326 : 포스터가 전체 레코드의 ** 정확한 ** 일치를 요구하지 않았기 때문에. 이 질문은 레코드의 두 필드 (이름 및 주소)가 일치하는지 묻고 네 개의 필드가 있습니다. 나는 하나의 필드 (다른 세 가지의 내용에 관계없이)와 둘 이상의 필드의 조합을 찾기 위해 그것을 변경하는 방법을 설명하는 텍스트를 찾기위한 코드를 제공했다. 데이터 양이 속도를 염려 할 정도로 높으면 검색 기능을 향상시키기 위해 데이터를 저장하는 더 효율적이고 효과적인 방법이 있습니다. –

+0

@user CompareMem은 여기서 작동하지 않습니다. 그것은 또한 일반적으로 그것을 사용하는 실수입니다. 할당되었지만 초기화되지 않은 각 문자열의 문자를 생각해보십시오. 그리고 패딩과 정렬에 대해 생각해보십시오. –