字典是这种情况下最好的数据结构吗

本文关键字:数据结构 这种情况下 字典 | 更新日期: 2023-09-27 17:58:46

我需要一个

Dictionary< long, List<Person> > 

人员具有ID和Value属性。

我希望能够通过ID获得列表,并且能够从该集合中轻松找到具有特定ID的人。

Dictionary< long, Dictionary<long, string> >是否

唯一能快速完成这项工作的好方法?或者在这种情况下还有其他更简单或更好的数据结构可以使用吗?

编辑:此外,对于查找,如果我只有个人ID,那么我仍然必须循环浏览原始字典才能获得该值。谢谢,

字典是这种情况下最好的数据结构吗

如果速度是可测量的问题,我只会使用Dictionary<long, List<Person>>(或者可能只使用Dictionary<long, IEnumerable<Person>>),并且更改结构。那么一个查找就是:

outerDict[listID].First(p => p.ID == personID);

使用Dictionary<long, Dictionary<long, Person>>:的几个缺点

  • 如果一个人的ID发生了变化,您需要有意地将其移动到Dictionary中的另一个bucket中(没有框架结构可以为您做到这一点)
  • 如果您只想要一个Person的列表,或者需要通过ID以外的属性查找人员,那么这种结构只会使遍历内部集合变得有点困难

如果这两者都不令人担忧,那么Dictionary<long, Dictionary<long, Person>>肯定会更快,但除非你同时尝试并测量它们,否则你不知道会快多少。

根据您的编辑(假设一个人的列表ID和个人ID从未更改),另一种选择可能是将所有数据加载到一个平面列表中,并通过ListID创建查找,通过PersonID:创建字典

List<Person> people = {load list};
var peopleByListID = people.GroupBy(p => p.ListID).ToLookup();
var peopleByID = people.ToDictionary(p => pID, p => p);

这样,您就可以使用最适合您需求的任何结构。创建查找和字典会有一些额外的开销,因此除非您需要不断返回原始源,否则这些将在搜索中提供显著的性能优势。

您实际上拥有一个双键字典。您需要有两个长值才能访问字典的值。只需创建一个表示这两个ID值的复合对象,即可作为字典的关键字:

Dictionary<Tuple<long, long>, Person>

通过使用单个扁平字典,而不是嵌套字典,可以防止内存中的碎片,并限制字典的开销。如果您想稍微提高可读性,可以创建自己的自定义对象来表示密钥(只需确保有效地覆盖GetHashCodeEquals),而不是使用Tuple