0

After completing a task in Java, I have now been required to produce the same results in C# and I am in need of some help. The object that I am using is:

Dictionary<int, Dictionary<String, List<int>>> full_map = new Dictionary<int, Dictionary<String, List<int>>>();

I want to add an entry to the inner dictionary if I already have something stored at the main dictionary's key.

To handle this, I started with the logic,

if (full_map.ContainsKey(int.Parse(pop_cy_st_intrst[0])))
{
    Dictionary<String, List<int>> temp = new Dictionary<String, List<int>>();
    //this is the logic I can't figure out.
}
else
{
    full_map.Add(int.Parse(pop_cy_st_intrst[0]), temp_entry);
}

My thought process for the if statement was to store the existing dictionary in the temp and add the new entry to it. Then, put the updated dictionary back at the key location but it keeps throwing me errors.

Flimzy
  • 60,850
  • 13
  • 104
  • 147
Jeremiah T
  • 23
  • 3

4 Answers4

0

I believe this would work:

if (full_map.ContainsKey(int.Parse(pop_cy_st_intrst[0])))
    full_map[int.Parse(pop_cy_st_intrst[0])].Add(innerKeyStr, innerValueList);
else
    full_map.Add(int.Parse(pop_cy_st_intrst[0]), new Dictionary<string, List<int>>());

So if the full_map outer dictionary contains the key, then you access the inner dictionary based on that key and add whatever you want (I don't know if it's pop_cy_st_intrst[0] for the inner key as well, so I just leave that up to you).

If full_map does not contain the key, then you add a new inner dictionary for that key.

If you want to add to the inner dictionary whether or not that inner dictionary existed already, then that last line could be

full_map.Add(int.Parse(pop_cy_st_intrst[0]), new Dictionary<string, List<int>>() { { innerKeyStr, innerValueList } });
Jashaszun
  • 8,903
  • 3
  • 21
  • 51
  • 1
    _"you should use string instead"_ - I disagree with the "should". It's a matter of preference. – cbr Jul 09 '15 at 16:57
  • 1
    *string"/"String", "int"/"System.Int32", "Tomato"/"Tomaato" - doesn't matter. string is just an alias to String. http://stackoverflow.com/questions/7074/whats-the-difference-between-string-and-string – Jason W Jul 09 '15 at 17:04
  • This works beautifully. Thanks I don't know how I didn't see that! Also, does the wrapper String class just give me more flexibility? I first wondered why there is a String wrapper and not an Integer one. – Jeremiah T Jul 09 '15 at 17:05
  • 1
    It's not a wrapper - it's alias. Using `string` and `String` are completely identical, just like `int` is completely identical in c# to `System.Int32` – Jason W Jul 09 '15 at 17:06
  • +3 to @JasonW with the bonus knowledge. – Cory Jul 09 '15 at 17:08
  • @JeremiahT `string` and `int` are the C# language keywords - `String` and `Int32` are the .NET objects. – cbr Jul 09 '15 at 17:08
  • FYI, this will throw an exception is the Inner dictionary is NULL. Make sure you add error handling or checking like my answer does. – Mikanikal Jul 09 '15 at 17:32
  • @Mikanikal The inner dictionary should never be null. If there is no inner dictionary for a specific key, I assign a new dictionary to that key. I never assign `null` to any of the outer dictionary's keys. – Jashaszun Jul 09 '15 at 17:33
  • @Jashaszun You simply check for an existing key. You never check to see if full_map[key] == null. Neither your code or the code from the OP shows full_map being built. It may already have values in it when it gets to this logic. Who knows?..... Just adding a small tidbit in case there are already values in full_map and they have null inner dictionaries. If OP always builds full_map from scratch then it wont matter, but its something to keep in mind. – Mikanikal Jul 09 '15 at 17:37
  • @Mikanikal Yeah, I see what you're saying. I guess I just assumed that this code was the *only* code populating the dictionaries. – Jashaszun Jul 09 '15 at 17:45
0

Use the index of the main dictionary to access the inner dictionary.

Dictionary<int, Dictionary<String, List<int>>> full_map = 
    new Dictionary<int, Dictionary<String, List<int>>>();

var index = int.Parse("10");

if (full_map.ContainsKey(index))
{
    if (full_map[index] == null)
    {
        full_map[index] = new Dictionary<string, List<int>>();
    }
}
else
{
    full_map.Add(index, new Dictionary<string,List<int>>());
}

full_map[index].Add("Blah", new List<int>());
Mikanikal
  • 990
  • 6
  • 11
0

I see there's been a few answers. Here's the one I was working while they got posted. Comments and such added for clarity.

Dictionary<int, Dictionary<String, List<int>>> full_map = new Dictionary<int, Dictionary<String, List<int>>>();

int key = 4;
if (full_map.ContainsKey(key))
{
    // the main dictionary has an entry

    // temp is the innerdictionary assigned to that key
    var temp = full_map[key];

    // add stuff to the inner dictionary
    temp.Add("string key",new List<int>());

}
else
{
    // the main dictionary does not have the key

    // create an inner dictionary
    var innerDictionary = new Dictionary<string,List<int>>();
    innerDictionary.Add("string key", new List<int>());

    // add it to the map with the key
    full_map.Add(key,innerDictionary);
}
Cory
  • 1,446
  • 9
  • 19
0

What about building your code using TryGetValue()? One call to review collection will be more efficient...