我声明了一种类似于以下内容的类型。

type
  TLikes = record
    Name            : string[20];
    favColours  : array of string[20];

  faves     = array of TLikes;


填充记录后,我将它们保存到二进制文件中,因此结构如下所示。

[John],     [Green]     [White]     [Blue]
[Paul],     [Blue]      [Red]       [White]     [Green]
[David],    [Red]       [Blue]      [Green]
[Bob],      [White]     [Blue]
[Peter],    [Blue]      [Green]     [Red]


例如,很容易找出David喜欢什么颜色。当我想知道谁喜欢蓝色时,会出现一个小问题。所以我要做的是建立第二个文件,就像这样……

[Blue],     [John]      [Paul]      [David]     [Peter]         [Bob]
[Red],      [David]     [Paul]      [Peter]
[White],    [Bob]       [David]     [John]      [Paul]
[Green],    [John]      [David]     [Paul]      [Peter]


但是有件事告诉我,我真的不需要创建第二个文件/数据结构,这似乎效率很低。

这是一个更大的问题……。

如果我需要找到谁喜欢大卫喜欢的东西的组合怎么办?我的结果是……

Blue and red and green  =   Paul, David, Peter
Blue and red            =   Paul, David, Peter
Blue and green          =   John, Paul, David, Peter
Red and Green           =   Paul, David, Peter


我的问题是。

有没有更好的方法来构造数据/记录,以便我可以找出鲍勃和保罗的共同点(蓝色和白色)或红色和白色的共同点(大卫和保罗)?

我想指出的是,我已尝试简化上述示例。实际上,Tlikes.Name的数据将是类似于…的字符串。

‘decabbadc’
‘bacddbcad’
‘eebadeaac’


这些字符串大约有200k +。 Tlikes.FavColours数据是一个文件名(这些文件大约有2k)。文件名指示包含Tlikes.Name字符串的文件。

我希望能够检索给定Tlikes.Name字符串的文件名列表或给定文件名的字符串列表。

注意:有些东西吸引我进入“集合”,但据我所知,我在集合中的元素数量有限,我走对了吗?

感谢您抽出宝贵的时间阅读帖子。

最佳答案

您正在这里处理多对多关系。
如果它是数据库,则意味着您要放入3个表:

1. People
2. Colors
3. Link table between 1 and 2


我建议您要么利用数据库来解决问题,要么在Delphi中对其建模,就像在数据库中一样。

使用Delphi结构
此外,停止使用shortstring它们已经过时,并且与长字符串相比具有零收益。
使用3个表格意味着您可以快速获得每种颜色的人员列表以及每种颜色的人员。

运作方式如下:

TPerson = record
  name: string;
  other_data....
end;

TPeople = array of TPerson;

TFavColor = record
  name: string;
  other_data....
end;

TFavColors = array of TFavColor;

TPersonColor = record
  PersonIndex: Cardinal;  <<-- index into the TPeople array
  ColorIndex: Cardinal;   <<-- index into the TFavColors array
end;

TPersonColors = array of TPersonColor;


现在,您可以循环遍历TPersonColors数组以提取数据。

使用数据库
在SQL中,这将更快,因为对您的数据进行了索引(总是应该对外键进行索引)。

查看所有喜欢蓝色和红色的人的SQL语句(此处使用MySQL语法):

SELECT p.name
FROM person p
INNER JOIN personcolor pc ON (pc.person_id = p.id)
INNER JOIN color c1 ON (pc.color_id = c1.id)
INNER JOIN color c2 ON (pc.color_id = c2.id)
WHERE c1.name = 'red' AND c2.name = 'blue'
GROUP BY p.id <<-- eliminate duplicates (not sure it's needed)


使用Delphi可以轻松地将数据库链接到您的应用程序。
这就是我建议的路线。

09-13 09:43