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

时间:2014-04-16 13:01:01

标签: c# dictionary

我需要有一个

Dictionary< long, List<Person> > 

Person具有ID和Value属性。

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

Dictionary< long, Dictionary<long, string> >

完成这项工作的唯一好方法是什么?或者在这种情况下是否有另一种更简单或更好的数据结构?

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

2 个答案:

答案 0 :(得分:1)

如果速度是可衡量的问题,我只会使用Dictionary<long, List<Person>>(或者只是Dictionary<long, IEnumerable<Person>>)而更改结构。然后查找就是:

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

使用Dictionary<long, Dictionary<long, Person>>

的一些缺点
  • 如果某个人的ID发生变化,您需要有意将其移至Dictionary中的其他存储区(没有为您执行此操作的框架结构)
  • 如果您只想要一个Person的列表,或者需要通过ID以外的属性查找人员,那么结构只会使遍历内部集合变得更加困难。< / LI>

如果这些都不是问题所在,那么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);

通过这种方式,您可以使用最适合您需求的结构。创建查找和字典还有一些额外的开销,因此,除非您需要不断回到原始源,否则这些将为搜索提供显着的性能优势。

答案 1 :(得分:1)

你基本上有一把双键词典。您需要有两个长值才能访问字典的值。只需创建一个表示这两个ID值的复合对象作为字典的关键字:

Dictionary<Tuple<long, long>, Person>

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