1

When building lookup tables that exceed a single dimension I find myself nesting dictionaries a lot:

public class MyLookupTable
{
    IDictionary<T1, IDictionary<T2, ISet<T3>>> mapOfMapOfSequences;

    // Update the table
    public void AddItem(T3 myItem);

    // Access the table
    public IEnumerable<T3> GetItems(T1 key1, T2 key2);
}

This has been working great for me so far, despite needing to write some wordy ContainsKey conditionals to access/modify the table.

Recently I am writing a caching mechanism that has 5 keys, and the dictionary field definition is a little ridiculous.

Architecturally, is there a design pattern I am completely overlooking that would make this problem a little more manageable?

Vesuvian
  • 638
  • 1
  • 6
  • 18
  • [Possible duplcate](https://stackoverflow.com/questions/9303859/is-a-deep-nested-dictionary-an-antipattern) – user202729 Apr 14 '18 at 13:55
  • Thank you! This is definitely pointing me in the right direction. – Vesuvian Apr 14 '18 at 14:01
  • It looks like you're doing fine. You have a custom type wrapping the dictionaries to be used properly (I'm assuming seeing the snippet you provided) and dictionaries are quite fast for lookup and storage. Personally I wouldn't suggest a better way unless I saw all the code and even then I'm sure you're doing it just fine. – Michael Puckett II Apr 14 '18 at 14:03
  • For your case a compound key would likely make sense. However it depends on the use case. If for example you need to know how many secondary key values exist for a given primary key then the nested form would make that operation more efficient. – juharr Apr 14 '18 at 14:07

1 Answers1

1

ValueTuples are helpful in creating ad-hoc types for scenarios like yours.

You could declare a dictionary like this:

IDictionary<(T1, T2, T3, T4, T5), TValue> dictionary;

Add values like this

dictionary.Add((k1, k2, k3, k4, k5), value);

You can find and example in the article Dissecting the tuples in C# 7 (MSDN).

You can also name the tuple items

IDictionary<(T1 key1, T2 key2, T3 key3, T4 key4, T5 key5), TValue> dictionary;

dictionary.Add((key1: k1, key2: k2, key3: k3, key4: k4, key5: k5), value);

Of course, you would choose speaking names adapted to your problem. Given a key, you can then access the tuple items like this:

var key = dictionary.Keys.First();
T3 k3 = key.key3;

or deconstruct the key with

var (k1, k2, k3, k4, k5) = dictionary.Keys.First();
Console.WriteLine($"Key 3 is {k3}");
Olivier Jacot-Descombes
  • 93,432
  • 11
  • 126
  • 171