【问题标题】:Searching a record which has been put into an array of records in delphi/lazarus搜索已放入 delphi/lazarus 记录数组中的记录
【发布时间】:2014-04-01 23:12:06
【问题描述】:

我有一个包含许多记录的数组。设置如下:

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

现在,假设我想在这个数组中搜索一个具有特定姓名特定地址的人。我该怎么办?所以基本上搜索的不仅仅是 1 个元素。 (我可以专门搜索 1 个属性,但不能过滤超过 1 个)

附件是我的表单设置的图片,这将更详细地显示我所指的内容:

【问题讨论】:

  • 循环遍历您的数组以查找匹配项。有人想知道为什么现在你使用固定长度的字符串。
  • @DavidHeffernan 这就是我的意思,我只能在我的数组中搜索 1 个特定事物时循环执行。你是怎么想的? :S
  • 最终会有一个循环遍历所有元素,通过某些标准检查匹配。如果你想找到多个匹配项,你可以这样做。如果您有具体问题,请告诉我们更多信息。
  • @DavidHeffernan 那是我唯一的问题:(你有空的时候能给我打一些代码作为例子吗?:)

标签: arrays delphi record pascal lazarus


【解决方案1】:

您只需迭代数组并检查循环中记录的多个属性。这是一个在姓名、地址、电话或电子邮件中搜索匹配项的示例;要将其更改为在多个记录属性中查找匹配项(如名称 地址),只需将测试中的 or 子句替换为使用 and 的两个或多个测试,如 @ 987654323@.

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;

使用示例:

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;

要匹配值的组合(例如NameAddress),只需适当更改if 中的条件:

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;

使用示例:

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

【讨论】:

  • 为什么不直接用 CompareMem 比较记录呢?您的 FindCustomer 不会返回完全匹配。
  • @user3060326:因为发帖人没有要求对整条记录进行精确匹配。该问题询问记录的两个字段(姓名和地址)之间的匹配,并且有四个字段。我给出了查找任何单个字段的代码(不管其他三个字段的内容)和解释如何更改它以查找两个或多个字段的任意组合的文本。如果数据量大到足以担心速度,则有更好、更有效的存储方式来提高搜索能力。
  • @user CompareMem 不能在这里工作。作为一般规则,使用它通常也是一个错误。考虑每个字符串中的字符,这些字符已分配但未初始化。并考虑填充和对齐。
  • @KenWhite 这就是我想要的,完全匹配。对不起,我应该更清楚。这段代码是我目前所在的位置,但这是我需要达到的步骤。有什么想法吗?
  • @user3478431:我的代码将为您提供与姓名、地址、电子邮件或电话完全匹配的信息。通过我提到的更改,您可以在两个、三个或四个字段上进行完全匹配。第一条评论所暗示的不是您要问的 - 我的代码(和附加文本)正是您正在寻找的解决方案。请参阅我编辑的答案。
猜你喜欢
  • 2011-04-20
  • 2017-06-12
  • 2018-01-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-25
  • 2016-05-24
相关资源
最近更新 更多