反向查找嵌套字典

时间:2011-05-21 02:04:02

标签: c# nested dictionary reverse-lookup

Dictionary<string, Dictionary<string, ... >...> nestedDictionary;

以上Dictionary从上到下在每个级别都有one-to-many个关系。添加项目非常简单,因为我们有叶子对象,我们从底部开始,创建词典并将每个添加到相关父级...

我的问题是当我想在内部词典中找到一个项目时。有两种选择:

  1. 嵌套foreach并找到该项目 然后快照所有循环 我们找到该项目并退出的那一刻 所有循环。然后我们知道项目 血统是 string1-&GT; string2-&GT; ...-&GT; stringN。 这个解决方案的问题是A) 性能B)线程安全(因为我想删除项目,如果父项没有子项则为父项,如果没有子项则为父项...)
  2. 创建反向查找字典 和索引添加的项目。某物 就像所有外围的Tuple一样 字典。然后将项目添加为 关键和所有外部父母一样 Tuple个成员。问题:A) 冗余B)保持同步 反向查找DictionaryDictionary
  3. 是否有快速且线程安全的解决方案?

2 个答案:

答案 0 :(得分:1)

看起来你实际上有两个以上的Dictionary级别。由于您无法使用此类型语法支持可变数量的词典:

 Dictionary<string, Dictionary<string, ... >...> nestedDictionary;

我只能假设它是一个大于2的数字。让我们说它是三个。对于您构建的任何数据结构,您有一个想要有效执行的预期用途和操作。

我假设你需要这样的电话:

var dictionary = new ThreeLevelDictionary();
dictionary.Add(string1, string2, string3, value);
var value = dictionary[string1, string2, string3];
dictionary.Remove(string1, string2, string3);

(对问题至关重要)您正在描述的反向查找:

var strings = dictionary.FindKeys(value);

如果这些是您需要执行并快速执行的操作,那么您可以使用的一个数据结构是带有Dictionary密钥的Tuple

public class ThreeLevelDictionary<TValue> : Dictionary<Tuple<string, string, string>, TValue>
{
    public void Add(string s1, string s2, string s3, TValue value)
    {
        Add(Tuple.Create(s1, s2, s3), value);
    }

    public TValue this[string s1, string s2, string s3]
    {
        get { return this[Tuple.Create(s1, s2, s3)]; }
        set { value = this[Tuple.Create(s1, s2, s3)]; }
    }

    public void Remove(string s1, string s2, string s3)
    {
        Remove(Tuple.Create(s1, s2, s3);
    }

    public IEnumerable<string> FindKeys(TValue value)
    {
        foreach (var key in Keys)
        {
            if (EqualityComparer<TValue>.Default.Equals(this[key], value))
                return new string[] { key.Item1, key.Item2, key.Item3 };
        }
        throw new InvalidOperationException("missing value");
    }
}

现在,如果性能表明这是一个瓶颈,那么您完全有能力使用另一个 Dictionary创建反向查找哈希表

如果以前喜欢的操作您要执行的操作,则此数据结构可能无法满足您的需求。无论哪种方式,如果您首先描述接口,总结您希望数据结构做什么,那么更容易看出是否还有其他选择。

答案 1 :(得分:1)

虽然我对C5 collection library几乎没有直接经验,但听起来你可以使用他们的TreeDictionary课程。它提供了一整套用于查找,迭代和修改树的有用方法,并且令人惊讶地记录在案。

另一种选择是使用QuickGraph库(可以在NuGet或codeplex上找到)。这涉及一些图论的知识,但在其他方面是一个非常有用的库。

两个库都要求您处理并发,就像标准的BCL集合一样。