TheWebs
TheWebs

Reputation: 12923

How to get the value out of this type of dictionary in c#

I want to create, because I understand dictionaries are key=>value in C#, a dictionary that is much like key=>value(key=>value)

Currently I I know I can do:

Dictionary<int, int> someVar = new Dictionary<int, int>();

which creates me a key=>value.

To create what I want I could do (this is just a guess, please correct me if I am wrong):

Dictionary<int Dictionray<int, int>> someVar = new Dictionary<int, Dictionray<int, int>>

Now comes the fun part, I want to do ONE and only ONE for loop over this dictponary object YET get all values so it would look something like:

foreach (KeyValuePair<int, int> pair in someVar){
    //object = base dictionary key
    //object2 = nested dictionary key
    //object3 = nested dictionary value 
}

Now I come from PHP so this would be dead easy to do in one for loop. what are your ideas? because I am new to C# and the term dictionary (even though php arrays are dictionaries).

I know in C# with a for loop like this I could do: pair.Key and pair.Value.

My second part, is How do I add values to such a dictionary? I know the typical .add(bla, bla) but how do you add values to the nested part?

Upvotes: 3

Views: 1626

Answers (3)

Ben Reich
Ben Reich

Reputation: 16324

Iterating

In C#, IDictionary<TKey, TValue> implements IEnumerable<KeyValuePair<TKey, TValue>>. So, you can iterate over an instance of type IDictionary<TKey, TValue> using foreach or a Linq query, and get every KeyValuePair in the data structure. Since your TValue is in this case itself an IDictionary, you can do this on the inner structure as well:

foreach(var kvp in myDictionary)
{
    foreach(var innerKvp in kvp.Value)
    {
         var myValue = innerKvp.Value
         //Logic on myValue
    }
}

Using the Linq library, you can use SelectMany to get all of the KeyValuePair instances quite elegantly:

myDictionary.SelectMany(kvp => kvp.Value);

SelectMany essentially flattens a list of lists. This Linq query is saying: for each key value pair in my dictionary, get all the inner dictionaries, treat them as lists of key value pairs, and then flatten all those lists. This will return an IEnumerable<KeyValuePair<TKey, TValue>>.

If instead you only care about the values of the inner dictionary, and not the keys, you can use the Values property on IDictionary<TKey, TValue> which returns an IEnumerable<TValue> of all the values in the dictionary. We can then use SelectMany to get a list that contains all the values in the dictionary of dictionaries:

myDictionary.Values.SelectMany(dict => dict.Values);

Read more about IDictionary<TKey, TValue> here and more about KeyValuePair<TKey, TValue> here.

Adding

In order to add an element to this data structure, you'll have to first check if the inner dictionaries are null. Let's say we're trying to add 3 to the dictionary keyed by 2 in the dictionary keyed by 1:

var myInnerDictionary = myDictionary.ContainsKey(1) ? myDictionary[1] : (myDictionary[1] = new Dictionary<int, int>());
myInnerDictionary[1][2] = 3;

Of course this will override a value in that location if it already exists, so you might want to check that as well, or use the Add method, which will not overwrite.

You should also learn about the ToDictionary Linq method which can help you construct dictionaries from other IEnumerables. Read about it here.

Upvotes: 4

Andrey Gordeev
Andrey Gordeev

Reputation: 32469

It's impossible to get all the values including nested by using only one foreach loop, unless nested Dictionaries have a values which you can get without using loop, like this:

foreach (var pair in someVar){
    var object1 = (Dictionary<int,int>)pair.Value;
    var object2 = object1[0].Value;
    var object3 = object1[1].Value; 
    .....

    // To add a values to the nested Dictionary just use Dictionary.Add method:
    object1.Add(1,1);
}

Upvotes: 0

Kevin Nacios
Kevin Nacios

Reputation: 2853

use linq to get all the values

var values = someVar.SelectMany(x => x.Values);

as for how to add values to the nested part, you'd just need the key for the outer dictionary for which sub dictionary you want to to add it to:

someVar[key].Add(0, 0);

Upvotes: 0

Related Questions