Best implementation for Key Value Pair Data Structure?
Asked Answered
H

9

79

So I've been poking around with C# a bit lately, and all the Generic Collections have me a little confused. Say I wanted to represent a data structure where the head of a tree was a key value pair, and then there is one optional list of key value pairs below that (but no more levels than these). Would this be suitable?

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;
}

It's only really a simple shunt for passing around data.

Hydromedusa answered 12/8, 2008 at 13:12 Comment(0)
N
144

There is an actual Data Type called KeyValuePair, use like this

KeyValuePair<string, string> myKeyValuePair = new KeyValuePair<string,string>("defaultkey", "defaultvalue");
Nova answered 12/8, 2008 at 13:20 Comment(3)
This works great with a "using" statement (similar to the old typedef) in order to save some typing and make everything clearer. If you constantly use e. g. the (string, string) pair.Neron
KeyValuePair<string, string> NAME_HERE = new KeyValuePair<string,string>("defaultkey", "defaultvalue");Aguish
To expand on @AndreasReiff 's comment: using NameValuePair = System.Collections.Generic.KeyValuePair<string, string>; near the top of each file that needs a (string, string) struct. Though I found it more convenient to create a class NameValuePair in my namespace: 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; } } } Vicissitude
A
14

One possible thing you could do is use the Dictionary object straight out of the box and then just extend it with your own modifications:

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

This gives you the advantage of not having to enforce the rules of IDictionary for your Key (e.g., key uniqueness, etc).

And yup you got the concept of the constructor right :)

Anon answered 12/8, 2008 at 13:25 Comment(0)
G
7

I think what you might be after (as a literal implementation of your question), is:

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

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

You did actually say a "list" of key-values in your question, so you might want to swap the inner IDictionary with a:

IList<KeyValuePair<string, string>>
Gettogether answered 12/8, 2008 at 13:45 Comment(0)
I
5

There is a KeyValuePair built-in type. As a matter of fact, this is what the IDictionary is giving you access to when you iterate in it.

Also, this structure is hardly a tree, finding a more representative name might be a good exercise.

Isolation answered 12/8, 2008 at 13:23 Comment(0)
H
3

Just one thing to add to this (although I do think you have already had your question answered by others). In the interests of extensibility (since we all know it will happen at some point) you may want to check out the Composite Pattern This is ideal for working with "Tree-Like Structures"..

Like I said, I know you are only expecting one sub-level, but this could really be useful for you if you later need to extend ^_^

Heterotopia answered 12/8, 2008 at 13:45 Comment(0)
S
2

@Jay Mooney: A generic Dictionary class in .NET is actually a hash table, just with fixed types.

The code you've shown shouldn't convince anyone to use Hashtable instead of Dictionary, since both code pieces can be used for both types.

For hashtable:

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);
}

For dictionary:

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

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

And just the same for the other one with KeyValuePair, just use the non-generic version for Hashtable, and the generic version for Dictionary.

So it's just as easy both ways, but Hashtable uses Object for both key and value, which means you will box all value types, and you don't have type safety, and Dictionary uses generic types and is thus better.

Stephanotis answered 12/8, 2008 at 13:25 Comment(0)
B
2

Key value Pair is a Datatype in C#. You can you it like this:

List<KeyValuePair<string, string>> arrFileName = new List<KeyValuePair<string, string>>(); 

You can Iterate this List and access the key and value.

foreach (KeyValuePair<string, string> ele in arrFileName)
{ FileName = ele.Key;
  string filepath = ele.Value;} I have used it for accessing filename and filepath.                   
Basting answered 30/6, 2023 at 5:54 Comment(1)
Thank you for your interest in contributing to the Stack Overflow community. This question already has quite a few answers—including one that has been extensively validated by the community. Are you certain your approach hasn’t been given previously? If so, it would be useful to explain how your approach is different, under what circumstances your approach might be preferred, and/or why you think the previous answers aren’t sufficient. Can you kindly edit your answer to offer an explanation?Opia
S
1

Dictionary Class is exactly what you want, correct.

You can declare the field directly as Dictionary, instead of IDictionary, but that's up to you.

Stephanotis answered 12/8, 2008 at 13:22 Comment(0)
S
1

Use something like this:

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

It's ugly, but I think it will give you what you want. Too bad KeyValuePair is sealed.

Stinkwood answered 12/8, 2008 at 13:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.