arraysdelphirecordlazarus

Searching a record which has been put into an array of records in Delphi/Lazarus


I have an array holding many records set up like this:

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

Now, let’s say I wanted to search this array for a person with a certain name and certain address. How would I go about this? So basically searching more than just one element. (I can search for specifically one property but can’t filter more than one.)

Attached is a picture of how my form is set up and this’ll show in more detail as to what I’m referring to:

Search form


Solution

  • You just iterate the array and check multiple properties of the record in your loop. Here's an example that searches for a match in either name, address, phone, or email; to change it to look for a match in multiple record properties (like name and address), just replace the or clauses in the test with two or more tests using and instead, as in if (Customers[Idx].Name = Name) and (Customers[Idx].Address = Address) then.

    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;
    

    Sample use:

    var
      Idx: Integer;
    begin
      // Customers is your array of TCustomer in a TCustomerList
      Idx := FindCustomer('', '', '', 'jsmith@example.com', 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;
    

    To match on a combination of values (such as Name and Address), just change the condition in the if appropriately:

    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;
    

    Sample use:

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