基本上我想要像Dictionary< Tkey1,TKey2,TValue>这样的东西,但不是(正如我在其他问题中看到的那样)和AND中的键,但是在OR中。为了更好地解释:我希望能够在字典中找到只提供其中一个键的元素,而不是两者。
我还认为我们应该考虑线程安全性以及轻松扩展到Dictionary< Tkey1,TKey2,TKeyN,TValue>的能力。溶液...
答案 0 :(得分:21)
我将使用这两个词典实现数据结构
Dictionary<TKey1, KeyValuePair<TKey2, TValue>> dict1;
Dictionary<TKey2, KeyValuePair<TKey1, TValue>> dict2;
这样,如果您获得1个密钥,则同时拥有值和其他密钥以便于删除和更新。
答案 1 :(得分:12)
所以你想要一个多索引词典,支持基于任何键的查找,并支持多个键的扩展?
也许您正在考虑错误的数据结构,请尝试使用KD-Tree。不可变的KD树将满足线程安全要求。
KD-tree比朴素Dictionary{Key1, Dictionary{Key2, Value}}
方法有一些主要优势,即你可以在不知道Key1的情况下搜索基于Key2的所有字段。此外,KD树允许您搜索 near 其他键的键。例如,约会网站将人们分为几十个群体(吸烟者/非吸烟者,性别,宗教,生活方式,年龄,身高),然后根据您的查询返回最近的邻居。
这是一个C#和Java实现:
答案 2 :(得分:5)
我会在这里走出去并且显得愚蠢,但你可以根据两个字典滚动你自己的字典。写入(即使使用锁定机制来确保线程安全)也不会太困难。我的意思是,有很多例子可以使用索引或密钥来访问集合。 (如会话)
相反,如果您的多个索引属于同一类型,则可以多次添加相同的项目。
Dictionary将支持具有GUID索引的内容,以及简单的名称索引“Joe” - 您必须记住将该项添加两次。
答案 3 :(得分:2)
您可以只使用常规字典并插入值两次,每个键一次。要删除,请删除这两个键。
上升空间:
缺点:
size()
加倍。答案 4 :(得分:2)
也许是一个选择:
按照约翰库格曼的建议,只需在同一个字典中添加两次。然后你保留第二个字典,将值映射到键集。
添加键值对时,只需将其正常添加到第一个词典中,然后从第二个词典中检索属于该值的键集并添加键。
Dictionary<TKey, TValue> dict1;
Dictionary<TValue, ICollection<TKey>> dict2;
通过从dict2中检索密钥集并从dict1逐个删除它来完成删除值。
键的数量是dict1.Count,值的数量是dict2.Count
答案 5 :(得分:1)
您是否考虑过持有两个词典,每个词一个?添加项目会将其添加到两者中。
删除意味着从两个词典中删除,并且需要两个键。要仅使用一个键删除,该项必须存储两个键。如果它还没有同时保存两个键,则可以将其包装在容纳对象和项目的容器对象中。
答案 6 :(得分:0)
两个字典,但不要复制每个字典。
您将拥有一个值字典和一个密钥字典。
当您调用add方法时,您将生成GUID并将其添加到密钥字典中。
然后,使用GUID作为值字典的键。
如果要添加两个键,您将使用相同的GUID将另一个项添加到键字典中。
当然这意味着每次查找都需要对数据进行两次检查,但即使您有50个相同值的密钥也不会更多。
根据keys表中的键查找guid,然后根据values表中的guid查找数据。
答案 7 :(得分:0)
我写了这样一本字典并将其发布在my blog上。它会给你一个很好的API:
DoubleKeyDictionary<int, string, string> books = new DoubleKeyDictionary<string, string, string>();
bookListEx.Add(1, “21/12/2009″, “Lord of the Rings - Fellowship of the Ring”);
您也可以在两个字典上执行“Equals”,并在每个字典上执行“Equals”。
请注意,代码中至少有一个错误(在评论中发现)并且没有单元测试等。当(是的!)我得到一些时间我会更新代码单元测试...
答案 8 :(得分:0)
多索引容器inspired by boost ??
怎么样?看看CodeProject。
答案 9 :(得分:0)
创建简单的类来存储Tkey1,TKey2,TValue,制作它们的列表并使用LINQ查询这样的结构将是一个选项。
答案 10 :(得分:0)
查看CodeProject上的这篇文章:http://www.codeproject.com/KB/recipes/multikey-dictionary.aspx
这显然是做多键字典的正确方法;)