.NET Tips and Tricks

Blog archive

Accessing a Dictionary Using Multiple Keys

Dictionaries and some other collection objects allow you to store an item along with a key value. This allows you to retrieve the item later, either by position or by key value. This code stores a value under the key "PHVIS," and finishes by setting the variable Result to "Peter Vogel":

Dim Items As New Dictionary(Of String,  String)
Items.Add("PHVIS", "Peter  Vogel")
Dim Result As String
Result = Items("PHVIS")  

But what if you want to store something by two values -- storing sales amounts by CustomerName and SaleDate, for instance? You could just concatenate two values together to create a single key, but a better solution would be to define a class to hold the two values to use as the key. Unfortunately, using a class won't work. When testing for equality, these collections will use an object's hashcode, returned from the class' GetHashCode method, to determine if two objects are identical. Two different objects, even if they're from the same class and have identical values in their properties, are considered to be different under this test.

But if you use a Structure instead,, everything works. Structures are scalar types rather than reference types like objects, so their values are compared to determine equality. A structure to hold two values might look like this:

Structure TwoValue
  Public CustomerId As String
  Public SaleDate As DateTime
End Structure

To use this structure, you might store a customer's sales under the customer's identifier, and the date that the sale was made:

Dim Items As New Dictionary(Of TwoValue, Integer)
Dim Key As TwoValue
Key.CustomerId = "A123"
Key.SaleDate =  Date.Parse("11/01/2010")
Items.Add(Key, 132)

Retrieving the value just consists of assembling a matching key and passing the key to the Dictionary. This example will retrieve the value and puts it in the variable Result: 

Dim Result As Integer
Dim Key2 As TwoValue
Key2.CustomerId = "A123"
Key2.SaleDate =  Date.Parse("11/01/2010")

Result = items(Key2)

Posted by Peter Vogel on 04/04/2012 at 1:16 PM

comments powered by Disqus

Reader Comments:

Sat, Apr 7, 2012 Peter Vogel Canada

Jason: I missed your point! I didn't realize that you meant you were using tuples as the key value (though, in retrospect, it seems obvious that's what you meant). I think that's an excellent move provided you don't mind (as you noted) giving up the IntelliSense for the key's values--wish that I'd thought of it.

Fri, Apr 6, 2012 Jason

I might be misreading this. The bottom line allows you to run a lookup in the dictionary when you know the key. The example I had is that account #'s where I work is acct # and suffix...so i have both those pieces just just run the following code below. It runs a lookup without looping through the dictionary. Its a bit more wordy then using a struct. Dictionary, string> myDictionary = new Dictionary, int>(); MessageBox.Show(myDictionary[new Tuple(2,"2")]);

Fri, Apr 6, 2012 Peter Vogel Canada

Jason: I've discussed tuples in other columns (I'm very found of tuples). But tuples don't let you retrieve items by name--which is really the goal of a Dictionary. With a tuple, to find the item I'd want by key name, I'd have to loop through them. The Le: Generally speaking, if I'm not accessing the disk (or making a call to another computer), I don't worry about the performance implications as much as I worry about the simplicity/readability/maintainability of my code. It would (I suspect) require an absolutely huge collection or an enormous number of calls to the Dictionary to even begin to get a performance difference. For business applications, at least, performance is all about managing data access and only secondarily (and very secondarily) about your code.

Thu, Apr 5, 2012 The Le Akron, OH

How much of a performance hit would you take, using the structure rather than an integer or string?

Wed, Apr 4, 2012 Jason

Why not just a tuple? Tuple has worked perfectly in this situation for me. The only difference is you get item1 item 2 instead of .CustomerId and .SaleDate It prevents you from creating a one off class though.

Add Your Comments Now:

Your Name:(optional)
Your Email:(optional)
Your Location:(optional)
Please type the letters/numbers you see above

.NET Insight

Sign up for our newsletter.

I agree to this site's Privacy Policy.