Consider this:
public void ReadEachItemInTheDictionary<V>(V value)
{
// I know that value is a dictionary
// where the key and value are scalars
// or primitive types or value types
if (value.GetType().IsGenericType &&
value.GetType().GetGenericTypeDefinition() ==
typeof(Dictionary<,>))
{
// I know the System.Type of each type
// argument of the dictionary
var keyType = value.GetType().GetGenericArguments()[0];
var valueType = value.GetType().GetGenericArguments()[1];
// Now, I want to do something like this:
foreach(var keyValuePair in value)
{
// However, since at compile-time, there
// is no guarantee for the compiler that
// value is indeed an IEnumerable<KeyValuePair<,>>
// that code won't work, obviously.
// I want to basically get a handle on the
// data
// I feel horrible. I should know this. And
// there was a time I did. Just feeling ashamed now.
}
}
}
Update
Looking at the two answers I have received, I feel compelled to highlight my problem again:
I only have the type parameter names of the key and value of the dictionary. Oh, I suddenly got the answer. Wait, I am posting it.
Update again
No, wait. What am I doing? Still unresolved.
This smells like abuse of generics, but anyway:
Put the foreach loop into a separate method that has the proper generic type parameters (probably, they will be the same that the dictionary has).
static void Read<TKey, TValue(Dictionary<TKey, TValue> dict) {
foreach(var keyValuePair in dict) { }
}
In that method you can use that dictionary like normal.
Call that method using reflection (MakeGenericMethod), or like this:
Read((dynamic)value);
You can not leave all the dictionary processing code statically typed. Only the call must be dynamic.
Generic Dictionary<> implements non-generic IDictionary, so you can cast and use it:
var dict = value as IDictionary;
foreach (var item in dict)
{
var entry = (DictionaryEntry)item;
// use entry.Key and entry.Value
}
I'll suggest an approach that is more cooperative with the type system. Your problem really boils down to the fact that KeyValuePair<TKey, TValue> doesn't implement a non-generic interface, otherwise you could simply cast the dictionary to IEnumerable<NonGenericKeyValuePair>. However, Dictionary<TKey, TValue> does support the non-generic IDictionary, which has individual Keys and Values collections, so you can do this:
var dict = (IDictionary)input;
for each (var key in dict.Keys) {
var value = dict[key];
}
How forgetful of me. MakeGenericType is my friend.
http://msdn.microsoft.com/en-us/library/system.type.makegenerictype%28v=vs.110%29.aspx
Actually I need something like List<KeyValuePair<T, U>> but I want to be able to initialize it like dictionary (i.e. without writing new KeyValuePair every time). Like this:
Dictionary<string, string> dic = new Dictionary<string, string>
{
{ "key1", "value1"},
{ "key2", "value2"}
};
EDIT: It turns out .NET does have a combination list/dictionary type already: OrderedDictionary. Unfortunately this is a non-generic type, making it rather less attractive in my view. However, it retains the insertion order if you just call Add repeatedly.
It's a little strange as calling Add does not affect entries where a key already exists, whereas using the indexer to add a key/value pair will overwrite a previous association. Basically it doesn't seem like a terribly nice API, and I would personally still avoid it unless your use case exactly matches its behaviour.
No, .NET doesn't have any insertion-order-preserving dictionaries. You could always write your own list-based type with the relevant Add method. This might even be one of the few places I'd consider extending an existing type:
public class KeyValueList<TKey, TValue> : List<KeyValuePair<TKey, TValue>>
{
public void Add(TKey key, TValue value)
{
Add(new KeyValuePair<TKey, TValue>(key, value));
}
}
Then:
var list = new KeyValueList<string, string>
{
{ "key1", "value1"},
{ "key2", "value2"}
};
An alternative is to use composition, but my gut feeling is that this is a reasonable use of inheritance. I can't place why I'm happy in this case but not usually, mind you...
Because you do not have a dictionary you cannot use a dictionary initiailzer. You have a list so you could use a list initializer which will be the closest you could get:
var l = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("key1", "value1"),
new KeyValuePair<string, string>("key2", "value2"),
};
Here's the minimum requirement for you to use dictionary initializer: the class must implement IEnumerable and the class must have a public method Add which takes 2 arguments (where the first argument represents the key and the second argument the value). So you could write a custom class which satisfies those requirements and you will be able to use the syntax you have shown in your question.
The code you have typed works fine - further to Mads Togersen's post about the implementation of collection initialisers, the compiler maps the brace-delimited entries ({"key1", "value1"} above) to an Add method on the collection with the same signature - in this case Dictionary.Add(TKey, TValue).
Dictionary<string, Dictionary<string, ... >...> nestedDictionary;
Above Dictionary has a one-to-many relationship at each level from top to bottom. Adding an item is pretty easy since we have the leaf object and we start from bottom, creating dictionaries and adding each to the relevant parent...
My problem is when I want to find an item at the inner Dictionaries. There are two options:
Nested foreach and find the item
then snapshot all the loops at the
moment we found the item and exit
all loops. Then we know item
pedigree is
string1->string2->...->stringN.
Problems with this solution is A)
Performance B) Thread-safety (since I want to remove the item, the parent if it has no child and it's parent if it has no child...)
Creating a reverse look-up dictionary
and indexing added items. Something
like a Tuple for all outer
dictionaries. Then add the item as
key and all the outer parents as
Tuple members. Problem: A)
Redundancy B) Keeping synchronized
reverse look-up Dictionary with
main Dictionary.
Any idea for a fast and thread-safe solution?
It looks like you actually have more than two levels of Dictionary. Since you cannot support a variable number of dictionaries using this type syntax:
Dictionary<string, Dictionary<string, ... >...> nestedDictionary;
I can only assume that it is some number greater than two. Let's say that it's three. For any data structure you construct, you have an intended use and operations that you want to perform efficiently.
I'm going to assume you need calls like this:
var dictionary = new ThreeLevelDictionary();
dictionary.Add(string1, string2, string3, value);
var value = dictionary[string1, string2, string3];
dictionary.Remove(string1, string2, string3);
And (critical to the question) the reverse lookup you are describing:
var strings = dictionary.FindKeys(value);
If these are the operations that you need to perform and to perform quickly, then one data structure that you can use is a Dictionary with a Tuple key:
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");
}
}
Now you are perfectly positioned to create a reverse-lookup hashtable using another Dictionary if performance indicates that this is a bottleneck.
If the previous liked operations are not the ones you want to perform, then this data structure might not meet your needs. Either way, if you describe the interface first that summarizes what you want the data structure to do, then it's easier to see if there are other alternatives.
Although I have little direct experience with the C5 collection library, it sounds like you could use their TreeDictionary class. It comes with a whole suite of useful methods for finding, iterating and modifying the tree, and is surprisingly well documented.
Another option would be to use the QuickGraph library (which you can find in NuGet or on codeplex). This involves some knowledge of graph theory but is otherwise a very useful library.
Both libraries require you to handle concurrency, just like the standard BCL collections.
I've seen a few different ways to iterate over a dictionary in C#. Is there a standard way?
foreach(KeyValuePair<string, string> entry in myDictionary)
{
// do something with entry.Value or entry.Key
}
If you are trying to use a generic Dictionary in C# like you would use an associative array in another language:
foreach(var item in myDictionary)
{
foo(item.Key);
bar(item.Value);
}
Or, if you only need to iterate over the collection of keys, use
foreach(var item in myDictionary.Keys)
{
foo(item);
}
And lastly, if you're only interested in the values:
foreach(var item in myDictionary.Values)
{
foo(item);
}
(Take note that the var keyword is an optional C# 3.0 and above feature, you could also use the exact type of your keys/values here)
In some cases you may need a counter that may be provided by for-loop implementation. For that, LINQ provides ElementAt which enables the following:
for (int index = 0; index < dictionary.Count; index++) {
var item = dictionary.ElementAt(index);
var itemKey = item.Key;
var itemValue = item.Value;
}
Depends on whether you're after the keys or the values...
From the MSDN Dictionary(TKey, TValue) Class description:
// When you use foreach to enumerate dictionary elements,
// the elements are retrieved as KeyValuePair objects.
Console.WriteLine();
foreach( KeyValuePair<string, string> kvp in openWith )
{
Console.WriteLine("Key = {0}, Value = {1}",
kvp.Key, kvp.Value);
}
// To get the values alone, use the Values property.
Dictionary<string, string>.ValueCollection valueColl =
openWith.Values;
// The elements of the ValueCollection are strongly typed
// with the type that was specified for dictionary values.
Console.WriteLine();
foreach( string s in valueColl )
{
Console.WriteLine("Value = {0}", s);
}
// To get the keys alone, use the Keys property.
Dictionary<string, string>.KeyCollection keyColl =
openWith.Keys;
// The elements of the KeyCollection are strongly typed
// with the type that was specified for dictionary keys.
Console.WriteLine();
foreach( string s in keyColl )
{
Console.WriteLine("Key = {0}", s);
}
Generally, asking for "the best way" without a specific context is like asking
what is the best color?
One the one hand, there are many colors and there's no best color. It depends on the need and often on taste, too.
On the other hand, there are many ways to iterate over a Dictionary in C# and there's no best way. It depends on the need and often on taste, too.
Most straightforward way
foreach (var kvp in items)
{
// key is kvp.Key
doStuff(kvp.Value)
}
If you need only the value (allows to call it item, more readable than kvp.Value).
foreach (var item in items.Values)
{
doStuff(item)
}
If you need a specific sort order
Generally, beginners are surprised about order of enumeration of a Dictionary.
LINQ provides a concise syntax that allows to specify order (and many other things), e.g.:
foreach (var kvp in items.OrderBy(kvp => kvp.Key))
{
// key is kvp.Key
doStuff(kvp.Value)
}
Again you might only need the value. LINQ also provides a concise solution to:
iterate directly on the value (allows to call it item, more readable than kvp.Value)
but sorted by the keys
Here it is:
foreach (var item in items.OrderBy(kvp => kvp.Key).Select(kvp => kvp.Value))
{
doStuff(item)
}
There are many more real-world use case you can do from these examples.
If you don't need a specific order, just stick to the "most straightforward way" (see above)!
C# 7.0 introduced Deconstructors and if you are using .NET Core 2.0+ Application, the struct KeyValuePair<> already include a Deconstruct() for you. So you can do:
var dic = new Dictionary<int, string>() { { 1, "One" }, { 2, "Two" }, { 3, "Three" } };
foreach (var (key, value) in dic) {
Console.WriteLine($"Item [{key}] = {value}");
}
//Or
foreach (var (_, value) in dic) {
Console.WriteLine($"Item [NO_ID] = {value}");
}
//Or
foreach ((int key, string value) in dic) {
Console.WriteLine($"Item [{key}] = {value}");
}
I would say foreach is the standard way, though it obviously depends on what you're looking for
foreach(var kvp in my_dictionary) {
...
}
Is that what you're looking for?
You can also try this on big dictionaries for multithreaded processing.
dictionary
.AsParallel()
.ForAll(pair =>
{
// Process pair.Key and pair.Value here
});
I appreciate this question has already had a lot of responses but I wanted to throw in a little research.
Iterating over a dictionary can be rather slow when compared with iterating over something like an array. In my tests an iteration over an array took 0.015003 seconds whereas an iteration over a dictionary (with the same number of elements) took 0.0365073 seconds that's 2.4 times as long! Although I have seen much bigger differences. For comparison a List was somewhere in between at 0.00215043 seconds.
However, that is like comparing apples and oranges. My point is that iterating over dictionaries is slow.
Dictionaries are optimised for lookups, so with that in mind I've created two methods. One simply does a foreach, the other iterates the keys then looks up.
public static string Normal(Dictionary<string, string> dictionary)
{
string value;
int count = 0;
foreach (var kvp in dictionary)
{
value = kvp.Value;
count++;
}
return "Normal";
}
This one loads the keys and iterates over them instead (I did also try pulling the keys into a string[] but the difference was negligible.
public static string Keys(Dictionary<string, string> dictionary)
{
string value;
int count = 0;
foreach (var key in dictionary.Keys)
{
value = dictionary[key];
count++;
}
return "Keys";
}
With this example the normal foreach test took 0.0310062 and the keys version took 0.2205441. Loading all the keys and iterating over all the lookups is clearly a LOT slower!
For a final test I've performed my iteration ten times to see if there are any benefits to using the keys here (by this point I was just curious):
Here's the RunTest method if that helps you visualise what's going on.
private static string RunTest<T>(T dictionary, Func<T, string> function)
{
DateTime start = DateTime.Now;
string name = null;
for (int i = 0; i < 10; i++)
{
name = function(dictionary);
}
DateTime end = DateTime.Now;
var duration = end.Subtract(start);
return string.Format("{0} took {1} seconds", name, duration.TotalSeconds);
}
Here the normal foreach run took 0.2820564 seconds (around ten times longer than a single iteration took - as you'd expect). The iteration over the keys took 2.2249449 seconds.
Edited To Add:
Reading some of the other answers made me question what would happen if I used Dictionary instead of Dictionary. In this example the array took 0.0120024 seconds, the list 0.0185037 seconds and the dictionary 0.0465093 seconds. It's reasonable to expect that the data type makes a difference on how much slower the dictionary is.
What are my Conclusions?
Avoid iterating over a dictionary if you can, they are substantially slower than iterating over an array with the same data in it.
If you do choose to iterate over a dictionary don't try to be too clever, although slower you could do a lot worse than using the standard foreach method.
As already pointed out on this answer, KeyValuePair<TKey, TValue> implements a Deconstruct method starting on .NET Core 2.0, .NET Standard 2.1 and .NET Framework 5.0 (preview).
With this, it's possible to iterate through a dictionary in a KeyValuePair agnostic way:
var dictionary = new Dictionary<int, string>();
// ...
foreach (var (key, value) in dictionary)
{
// ...
}
There are plenty of options. My personal favorite is by KeyValuePair
Dictionary<string, object> myDictionary = new Dictionary<string, object>();
// Populate your dictionary here
foreach (KeyValuePair<string,object> kvp in myDictionary)
{
// Do some interesting things
}
You can also use the Keys and Values Collections
With .NET Framework 4.7 one can use decomposition
var fruits = new Dictionary<string, int>();
...
foreach (var (fruit, number) in fruits)
{
Console.WriteLine(fruit + ": " + number);
}
To make this code work on lower C# versions, add System.ValueTuple NuGet package and write somewhere
public static class MyExtensions
{
public static void Deconstruct<T1, T2>(this KeyValuePair<T1, T2> tuple,
out T1 key, out T2 value)
{
key = tuple.Key;
value = tuple.Value;
}
}
As of C# 7, you can deconstruct objects into variables. I believe this to be the best way to iterate over a dictionary.
Example:
Create an extension method on KeyValuePair<TKey, TVal> that deconstructs it:
public static void Deconstruct<TKey, TVal>(this KeyValuePair<TKey, TVal> pair, out TKey key, out TVal value)
{
key = pair.Key;
value = pair.Value;
}
Iterate over any Dictionary<TKey, TVal> in the following manner
// Dictionary can be of any types, just using 'int' and 'string' as examples.
Dictionary<int, string> dict = new Dictionary<int, string>();
// Deconstructor gets called here.
foreach (var (key, value) in dict)
{
Console.WriteLine($"{key} : {value}");
}
foreach is fastest and if you only iterate over ___.Values, it is also faster
Using C# 7, add this extension method to any project of your solution:
public static class IDictionaryExtensions
{
public static IEnumerable<(TKey, TValue)> Tuples<TKey, TValue>(
this IDictionary<TKey, TValue> dict)
{
foreach (KeyValuePair<TKey, TValue> kvp in dict)
yield return (kvp.Key, kvp.Value);
}
}
And use this simple syntax
foreach (var(id, value) in dict.Tuples())
{
// your code using 'id' and 'value'
}
Or this one, if you prefer
foreach ((string id, object value) in dict.Tuples())
{
// your code using 'id' and 'value'
}
In place of the traditional
foreach (KeyValuePair<string, object> kvp in dict)
{
string id = kvp.Key;
object value = kvp.Value;
// your code using 'id' and 'value'
}
The extension method transforms the KeyValuePair of your IDictionary<TKey, TValue> into a strongly typed tuple, allowing you to use this new comfortable syntax.
It converts -just- the required dictionary entries to tuples, so it does NOT converts the whole dictionary to tuples, so there are no performance concerns related to that.
There is a only minor cost calling the extension method for creating a tuple in comparison with using the KeyValuePair directly, which should NOT be an issue if you are assigning the KeyValuePair's properties Key and Value to new loop variables anyway.
In practice, this new syntax suits very well for most cases, except for low-level ultra-high performance scenarios, where you still have the option to simply not use it on that specific spot.
Check this out: MSDN Blog - New features in C# 7
Simplest form to iterate a dictionary:
foreach(var item in myDictionary)
{
Console.WriteLine(item.Key);
Console.WriteLine(item.Value);
}
I found this method in the documentation for the DictionaryBase class on MSDN:
foreach (DictionaryEntry de in myDictionary)
{
//Do some stuff with de.Value or de.Key
}
This was the only one I was able to get functioning correctly in a class that inherited from the DictionaryBase.
Sometimes if you only needs the values to be enumerated, use the dictionary's value collection:
foreach(var value in dictionary.Values)
{
// do something with entry.Value only
}
Reported by this post which states it is the fastest method:
http://alexpinsker.blogspot.hk/2010/02/c-fastest-way-to-iterate-over.html
I know this is a very old question, but I created some extension methods that might be useful:
public static void ForEach<T, U>(this Dictionary<T, U> d, Action<KeyValuePair<T, U>> a)
{
foreach (KeyValuePair<T, U> p in d) { a(p); }
}
public static void ForEach<T, U>(this Dictionary<T, U>.KeyCollection k, Action<T> a)
{
foreach (T t in k) { a(t); }
}
public static void ForEach<T, U>(this Dictionary<T, U>.ValueCollection v, Action<U> a)
{
foreach (U u in v) { a(u); }
}
This way I can write code like this:
myDictionary.ForEach(pair => Console.Write($"key: {pair.Key}, value: {pair.Value}"));
myDictionary.Keys.ForEach(key => Console.Write(key););
myDictionary.Values.ForEach(value => Console.Write(value););
If you want to use a for loop, you can do as below:
var keyList=new List<string>(dictionary.Keys);
for (int i = 0; i < keyList.Count; i++)
{
var key= keyList[i];
var value = dictionary[key];
}
I will take the advantage of .NET 4.0+ and provide an updated answer to the originally accepted one:
foreach(var entry in MyDic)
{
// do something with entry.Value or entry.Key
}
If say, you want to iterate over the values collection by default, I believe you can implement IEnumerable<>, Where T is the type of the values object in the dictionary, and "this" is a Dictionary.
public new IEnumerator<T> GetEnumerator()
{
return this.Values.GetEnumerator();
}
The standard way to iterate over a Dictionary, according to official documentation on MSDN is:
foreach (DictionaryEntry entry in myDictionary)
{
//Read entry.Key and entry.Value here
}
I wrote an extension to loop over a dictionary.
public static class DictionaryExtension
{
public static void ForEach<T1, T2>(this Dictionary<T1, T2> dictionary, Action<T1, T2> action) {
foreach(KeyValuePair<T1, T2> keyValue in dictionary) {
action(keyValue.Key, keyValue.Value);
}
}
}
Then you can call
myDictionary.ForEach((x,y) => Console.WriteLine(x + " - " + y));
Dictionary< TKey, TValue > It is a generic collection class in c# and it stores the data in the key value format.Key must be unique and it can not be null whereas value can be duplicate and null.As each item in the dictionary is treated as KeyValuePair< TKey, TValue > structure representing a key and its value. and hence we should take the element type KeyValuePair< TKey, TValue> during the iteration of element.Below is the example.
Dictionary<int, string> dict = new Dictionary<int, string>();
dict.Add(1,"One");
dict.Add(2,"Two");
dict.Add(3,"Three");
foreach (KeyValuePair<int, string> item in dict)
{
Console.WriteLine("Key: {0}, Value: {1}", item.Key, item.Value);
}
The best answer is of course: Think, if you could use a more appropriate data structure than a dictionary if you plan to iterate over it- as Vikas Gupta mentioned already in the (beginning of the) discussion under the question. But that discussion as this whole thread still lacks surprisingly good alternatives. One is:
SortedList<string, string> x = new SortedList<string, string>();
x.Add("key1", "value1");
x.Add("key2", "value2");
x["key3"] = "value3";
foreach( KeyValuePair<string, string> kvPair in x )
Console.WriteLine($"{kvPair.Key}, {kvPair.Value}");
Why it could be argued a code smell of iterating over a dictionary (e.g. by foreach(KeyValuePair<,>) ?
A basic principle of Clean Coding:
"Express intent!"
Robert C. Martin writes in "Clean Code": "Choosing names that reveal intent". Obviously naming alone is too weak. "Express (reveal) intent with every coding decision" expresses it better.
A related principle is "Principle of least surprise" (=Principle of Least Astonishment).
Why this is related to iterating over a dictionary? Choosing a dictionary expresses the intent of choosing a data structure which was made for primarily finding data by key. Nowadays there are so much alternatives in .NET, if you want to iterate through key/value pairs that you could choose something else.
Moreover: If you iterate over something, you have to reveal something about how the items are (to be) ordered and expected to be ordered!
Although the known implementations of Dictionary sort the key collection in the order of the items added-
AFAIK, Dictionary has no assured specification about ordering (has it?).
But what are the alternatives?
TLDR:
SortedList: If your collection is not getting too large, a simple solution would be to use SortedList<,> which gives you also full indexing of key/value pairs.
Microsoft has a long article about mentioning and explaining fitting collections:
Keyed collection
To mention the most important: KeyedCollection<,> and SortedDictionary<,> .
SortedDictionary<,> is a bit faster than SortedList for only inserting if it gets large, but lacks indexing and is needed only if O(log n) for inserting is preferenced over other operations. If you really need O(1) for inserting and accept slower iterating in exchange, you have to stay with simple Dictionary<,>.
Obviously there is no data structure which is the fastest for every possible operation..
Additionally there is ImmutableSortedDictionary<,>.
And if one data structure is not exactly what you need, then derivate from Dictionary<,> or even from the new ConcurrentDictionary<,> and add explicit iteration/sorting functions!
var dictionary = new Dictionary<string, int>
{
{ "Key", 12 }
};
var aggregateObjectCollection = dictionary.Select(
entry => new AggregateObject(entry.Key, entry.Value));
Just wanted to add my 2 cent, as the most answers relate to foreach-loop.
Please, take a look at the following code:
Dictionary<String, Double> myProductPrices = new Dictionary<String, Double>();
//Add some entries to the dictionary
myProductPrices.ToList().ForEach(kvP =>
{
kvP.Value *= 1.15;
Console.Writeline(String.Format("Product '{0}' has a new price: {1} $", kvp.Key, kvP.Value));
});
Altought this adds a additional call of '.ToList()', there might be a slight performance-improvement (as pointed out here foreach vs someList.Foreach(){}),
espacially when working with large Dictionaries and running in parallel is no option / won't have an effect at all.
Also, please note that you wont be able to assign values to the 'Value' property inside a foreach-loop. On the other hand, you will be able to manipulate the 'Key' as well, possibly getting you into trouble at runtime.
When you just want to "read" Keys and Values, you might also use IEnumerable.Select().
var newProductPrices = myProductPrices.Select(kvp => new { Name = kvp.Key, Price = kvp.Value * 1.15 } );
in addition to the highest ranking posts where there is a discussion between using
foreach(KeyValuePair<string, string> entry in myDictionary)
{
// do something with entry.Value or entry.Key
}
or
foreach(var entry in myDictionary)
{
// do something with entry.Value or entry.Key
}
most complete is the following because you can see the dictionary type from the initialization, kvp is KeyValuePair
var myDictionary = new Dictionary<string, string>(x);//fill dictionary with x
foreach(var kvp in myDictionary)//iterate over dictionary
{
// do something with kvp.Value or kvp.Key
}
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.
There is an actual Data Type called KeyValuePair, use like this
KeyValuePair<string, string> myKeyValuePair = new KeyValuePair<string,string>("defaultkey", "defaultvalue");
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 :)
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>>
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.
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 ^_^
#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.
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.
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.