如何实现多索引字典?

基本上我想要像Dictionary 这样的东西,但不是(正如我在其他问题中看到的那样)和AND中的键,但是在OR中。 为了更好地解释:我希望能够在字典中找到只提供其中一个键的元素,而不是两者。

我还认为我们应该考虑线程安全性以及轻松扩展到Dictionary 解决方案的能力……

我将使用这两个字典实现数据结构

Dictionary> dict1; Dictionary> dict2; 

这样,如果您获得1个密钥,则同时拥有值和其他密钥以便于删除和更新。

所以你想要一个多索引字典,支持基于任何键的查找,并支持多个键的扩展?

也许您正在考虑错误的数据结构,请尝试使用KD-Tree 。 不可变的KD树将满足线程安全要求。

KD树比天真的Dictionary{Key1, Dictionary{Key2, Value}}方法有一些主要的优点,即你可以在不知道Key1的情况下搜索基于Key2的所有字段。 此外,KD树允许您搜索其他键附近的键。 例如,约会网站将人们分为几十个群体(吸烟者/非吸烟者,性别,宗教,生活方式,年龄,身高),然后根据您的查询返回最近的邻居。

这是一个C#和Java实现:

http://home.wlu.edu/~levys/software/kd/

我会在这里走出去并且看起来很愚蠢,但你可以根据两个词典滚动你自己的词典。 写入起来并不是特别困难(即使使用锁定机制来确保线程安全)。 我的意思是,有很多例子可以使用索引或密钥来访问集合。 (如会话)

相反,如果您的多个索引属于同一类型,则可以多次添加相同的项目。

Dictionary将支持具有GUID索引的内容,以及简单的名称索引“Joe” – 您必须记住将项添加两次。

您可以为此使用常规字典并插入值两次,每个键一次。 要删除,请删除这两个键。

上升空间:

  • 可以使用一次查找搜索两个键。
  • 无需新代码。
  • 缩放到任意数量的键。

缺点:

  • 如果按键类型不同,则会失去类型安全性。
  • 无法迭代(key1,key2,value)元组。
  • 值出现两次,因此size()加倍。

也许一个选择:

按照约翰库格曼的建议,只需在同一个字典中添加两次。 然后你保留第二个字典,将值映射到键集。

当您添加一个键,值为par时,您只需将其正常添加到第一个字典中,然后从第二个字典中检索属于该值的键集并添加该键。

Dictionary dict1;
Dictionary> dict2;

通过从dict2检索密钥集并从dict1逐个删除它来完成删除值。

键的数量是dict1.Count,值的数量是dict2.Count

您是否考虑过持有两个词典,每个词一个? 添加项目会将其添加到两者。

删除意味着从两个字典中删除,并且需要两个键。 要仅使用一个键删除,该项必须存储两个键。 如果它还没有两个键,则可以将其包装在容纳键和项目的容器对象中。

两个字典,但不要复制每个字典中的项目。

你将拥有一个值字典和一个密钥字典。

当您调用add方法时,您将生成GUID并将其添加到密钥字典中。

然后,使用GUID作为值字典的键。

如果要添加两个键,则会使用相同的GUID将另一个项添加到键字典中。

当然,这意味着每次查找都需要对数据进行两次检查,但即使您有50个相同值的密钥也不会更多。

根据keys表中的键查找guid,然后根据values表中的guid查找数据。

我写了这样一本字典并将其发布在我的博客上 。 它会给你一个很好的API,如下所示:

 DoubleKeyDictionary books = new DoubleKeyDictionary(); bookListEx.Add(1, “21/12/2009″, “Lord of the Rings - Fellowship of the Ring”); 

您也可以在两个字典上执行“Equals”,并在每个字典上执行“Equals”。

请注意,代码中至少有一个错误(在评论中发现)并且没有unit testing等。 (是的!)我得到一些时间我会用unit testing更新代码…

那么多指数容器的灵感来自于提振 ?

看看CodeProject 。

创建简单的类来存储Tkey1,TKey2,TValue,制作它们的列表并使用LINQ来查询这样的结构将是一个选项。

查看CodeProject上的这篇文章: http : //www.codeproject.com/KB/recipes/multikey-dictionary.aspx

这显然是做多键字典的正确方法;)