1

I have to store two key one value in dictionary. So that i am using like this.

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

I have added key, key and value.

Dictionary<int, int> innerdict = new Dictionary<int,int>();
innerdict.Add(Month, Count);
dicThreatPurgeSummary.Add(Group, innerdict);

i am able to view value like this

int a = dicThreatPurgeSummary[Group][Month];

I need to update the value for dicThreatPurgeSummary[Group][Month] if it already exists. Please help me to find out this.

user1182553
  • 53
  • 2
  • 7

4 Answers4

4

Slightly more efficient than two calls to ContainsKey and three dictionary indexings:

Dictionary<int, int> forGroup;
if (dicThreatPurgeSummary.TryGetValue(Group, out forGroup) &&
    forGroup.ContainsKey(Month))
{
    forGroup[Month] = newValue;
}
Rawling
  • 49,248
  • 7
  • 89
  • 127
3

This should work

if(dicThreatPurgeSummary.ContainsKey(Group) &&
   dicThreatPurgeSummary[Group].ContainsKey(Month))
{
    dicThreatPurgeSummary[Group][Month] = NewValue;
}
juharr
  • 31,741
  • 4
  • 58
  • 93
0

You can use Dictionary<>.ContainsKey to check if a key exists, so you would do it like this:

if (dicThreatPurgeSummary.ContainsKey(Group))
{
    if (dicThreatPurgeSummary[Group].ContainsKey(Month))
    {
        // dicThreatPurgeSummary[Group][Month] exists
    }
}

Note that it might be better to use a two dimensional key instead of cascading two dictionaries. That way you won’t need to care to add a new dictionary every time you use a new key for the first level, and you would have all values in the same dictionary, allowing you to iterate over the values or check for values existance.

You could use a tuple for that:

var dicThreatPurgeSummary = new Dictionary<Tuple<int, int>, int>();
dicThreatPurgeSummary.Add(new Tuple<int, int>(Group, Month), Count);

// accessing the value
int a = dicThreatPurgeSummary[new Tuple<int, int>(Group, Month)];

// checking for existance
if (dicThreatPurgeSummary.ContainsKey(new Tuple<int, int>(Group, Month)))
{
    // ...
}

Using a prettier subtype

(untested)

class IntIntDict<T> : Dictionary<Tuple<int, int>, T>
{
    public T this[int index1, int index2]
    { get { return this[new Tuple(index1, index2)]; } }

    public bool ContainsKey (int index1, int index2)
    {
        return ContainsKey(new Tuple(index1, index2));
    }

    public void Add (int index1, int index2, T value)
    {
         Add(new Tuple(index1, index2), value);
    }
    // ...
}

And then you could just use it like this:

var dicThreatPurgeSummary = new IntIntDict<int>();
dicThreatPurgeSummary.Add(Group, Month, Count);

// accessing the value
int a = dicThreatPurgeSummary[Group, Month];

// checking for existance
if (dicThreatPurgeSummary.ContainsKey(Group, Month))
{
    // ...

}

poke
  • 369,085
  • 72
  • 557
  • 602
  • On one level using Tuple makes sense, but you do end up with much uglier code. – juharr Dec 06 '12 at 12:29
  • if (dic.ContainsKey(Group) && dic[Group].ContainsKey(Month)) { ... } – kol Dec 06 '12 at 12:29
  • @juharr You could probably make that prettier using some utility functions (extension methods) or even making a subtype of `Dictionary, T>` that has those directly (for example a `ContainsKey(int, int)` method). – poke Dec 06 '12 at 12:31
  • Composing the two `int`s into a `long`, or even into a single `int`, might be even better than using a `Tuple`. – Rawling Dec 06 '12 at 12:36
  • @Rawling Yeah, and if you go for a subtype, you could easily abstract those conversions away. – poke Dec 06 '12 at 12:41
0
Dictionary<int, int> innerDic = null;
bool isGroupPresent = dicThreatPurgeSummary.TryGetValue(Group, out innerDic);
if(isGroupPresent == false)
{
    //No entry for Group.
}
else
{
    int count;
    bool isMonthPresent = innerDic.TryGetValue(Month, out count);
    //Same as above
}
nakiya
  • 14,063
  • 21
  • 79
  • 118