关键值对数据结构的最佳实现?


74

所以最近我一直在玩C#,所有的Generic Collections让我有些困惑。假设我想表示一个数据结构,其中树的头部是一个键值对,然后在它下面有一个可选的键值对列表(但没有比这更多的级别了)。这样合适吗?

public class TokenTree
{
    public TokenTree()
    {
        /* I must admit to not fully understanding this,
         * I got it from msdn. As far as I can tell, IDictionary is an
         * interface, and Dictionary is the default implementation of
         * that interface, right?
         */
        SubPairs = new Dictionary<string, string>();
    }

    public string Key;
    public string Value;
    public IDictionary<string, string> SubPairs;
}

这只是传递数据的一个简单的分流器。

Answers:


137

有一个实际的数据类型称为KeyValuePair,像这样使用

KeyValuePair<string, string> myKeyValuePair = new KeyValuePair<string,string>("defaultkey", "defaultvalue");

1
这可以与“ using”语句(类似于旧的typedef)一起使用,以节省一些键入内容并使所有内容更清晰。如果您不断使用例如(string,string)对。
Andreas Reiff

8
KeyValuePair <字符串,字符串> NAME_HERE =新的KeyValuePair <字符串,字符串>(“ defaultkey”,“ defaultvalue”);
HasanAboShally 2013年

1
为了扩展@AndreasReiff的注释:using NameValuePair = System.Collections.Generic.KeyValuePair<string, string>;需要(string, string)结构的每个文件顶部附近。虽然我发现class NameValuePair在我的命名空间中创建更加方便: public class NameValuePair { KeyValuePair<string, string> it; public NameValuePair( string name, string value ) { it = new KeyValuePair<string, string>( name, value ); } public string Name { get { return it.Key; } } public string Value { get { return it.Value; } } }
ToolmakerSteve

12

您可能要做的一件事是直接使用Dictionary对象,然后使用您自己的修改对其进行扩展:

public class TokenTree : Dictionary<string, string>
{
    public IDictionary<string, string> SubPairs;
}

这为您提供了不必为密钥强制执行IDictionary规则的优点(例如,密钥唯一性等)。

是的,您对构造函数的概念很了解:)


7

我认为您可能想要做的(作为您问题的字面实现)是:

public class TokenTree
{
    public TokenTree()
    {
        tree = new Dictionary<string, IDictionary<string,string>>();
    }

    IDictionary<string, IDictionary<string, string>> tree; 
}

您确实在问题中说出了键值的“列表”,所以您可能想用以下内容交换内部值IDictionary

IList<KeyValuePair<string, string>>

5

有一个KeyValuePair内置类型。实际上,这是IDictionary在您进行迭代时为您提供的访问权限。

而且,这种结构很难说是一棵树,找到一个更具代表性的名称可能是一个不错的选择。


3

这只是一件事(尽管我确实认为您已经让别人回答了您的问题)。为了可扩展性(因为我们都知道它会在某个时刻发生),您可能需要查看Composite Pattern。这是使用“像树一样的结构”的理想选择。

就像我说的,我知道您只期望一个子级别,但是如果您以后需要扩展^ _ ^,这对您真的很有用。


2

@ Jay Mooney:.NET中的通用Dictionary类实际上是一个哈希表,只是具有固定的类型。

您显示的代码不应说服任何人使用Hashtable而不是Dictionary,因为两种代码段均可用于两种类型。

对于哈希表:

foreach(object key in h.keys)
{
     string keyAsString = key.ToString(); // btw, this is unnecessary
     string valAsString = h[key].ToString();

     System.Diagnostics.Debug.WriteLine(keyAsString + " " + valAsString);
}

对于字典:

foreach(string key in d.keys)
{
     string valAsString = d[key].ToString();

     System.Diagnostics.Debug.WriteLine(key + " " + valAsString);
}

对于使用KeyValuePair的其他对象,也是如此,仅对Hashtable使用非通用版本,对Dictionary使用通用版本。

因此,两种方法都一样简单,但是Hashtable使用Object作为键和值,这意味着您将装箱所有值类型,并且没有类型安全性,而Dictionary使用泛型类型,因此更好。



1

使用这样的东西:

class Tree < T > : Dictionary < T, IList< Tree < T > > >  
{  
}  

这很丑陋,但我想它将给您您想要的。KeyValuePair密封不好。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.