Click here to Skip to main content
Click here to Skip to main content

Bidirectional Hashtable

By , 31 Aug 2003
 

Introduction

Sometimes you have data with a 1:1 relationship that you put into a Hashtable, use for awhile, and later realize you need to look up the keys from the values in the table. This article introduces a class to solve this problem.

Background

The brain-dead solution is to have two hashtables (one forward, one backward), and add everything into both. This is a bit of a pain; why not have a class to manage this, and save ourselves from redundant typing? After having this problem a couple of times, I resolved to not type things in twice, anymore. Enter BidirHashtable, a bidirectional Hashtable.

Using the code

BidirHashtable is easy to create, though it doesn't support the rich set of constructors that Hashtable does.

BidirHashtable bh = new BidirHashtable();

The interface to BidirHashtable is essentially identical to that of Hashtable, except that internally it is managing two Hashtable objects. For example:

bh[1] = 101;
bh[2] = 102;

Caveat: You'll want to make sure only to use a 1:1 relationship. While 1:n relationships are impossible to establish with Hashtable or BidirHashtable, n:1 relationships are possible with Hashtable. BidirHashtable, however, is not designed with n:1 in mind, because for BidirHashtable it means a 1:n relationship for the reverse table--patently impossible. So be warned--and don't try it.

bh[1] = 101;
bh[2] = 101;  // don't try this

Checking whether elements are in the table is easy:

System.Diagnostics.Debug.Assert( bh.Contains(1) );
System.Diagnostics.Debug.Assert( bh.ContainsValue(101) );

Note the ContainsValue() function. This is in Hashtable, but in BidirHashtable, it is actually faster, as it does its lookup using the reverse table.

Forward lookups are also as in Hashtable:

System.Diagnostics.Debug.Assert( (int) bh[1] == 101 );

Reverse lookups, however, are new:

System.Diagnostics.Debug.Assert( (int) bh.ReverseLookup(101) == 1 );

For ease of use and efficiency, BidirHashtable also supports some conversions and additional ways to construct. For example:

public BidirHashtable(IDictionary dict)

This constructor takes a Hashtable or other IDictionary, and initializes the BidirHashtable from it.

Explicit casts are built in for both directions. Be warned, they result in the source object being cloned for the destination object. Still, they make using BidirHashtable, even easier:

Hashtable ht = (Hashtable) bh;
BidirHashtable bh2 = (BidirHashtable) ht;

This function creates a new BidirHashtable which is attached to the input Hashtable. Be careful in using it, but it can be a useful optimization:

public static BidirHashtable Attach(Hashtable ht)

If for any reason, you want the directions swapped, it's just a matter of swapping the internal Hashtable objects. This function accomplishes that:

public void ReverseDirection()

BidirHashtable implements IDictionary, ICollection, IEnumerable, and ICloneable. It does not (yet) implement ISerializable, though it could be added eventually.

Points of interest

Writing this class was one of those rare circumstances where, once it compiled, it basically worked. I did add a few things after the fact, but it's a simple class. You can find more information on my website.

History

  • 08-30-2003 - 1.0 - Initial revision

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Todd C. Gleason
Web Developer
United States United States
Member
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
Hint: For improved responsiveness ensure Javascript is enabled and choose 'Normal' from the Layout dropdown and hit 'Update'.
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralGenerics Version of this classmembermkg9 Dec '05 - 10:12 
GeneralRe: Generics Version of this classmemberJaredThirsk2 Mar '07 - 18:37 
GeneralRe: Generics Version of this classmemberJaredThirsk2 Mar '07 - 18:41 
GeneralSourcememberDiego Mijelshon2 Sep '03 - 3:32 
Nice article. But you should write about both the use and the implementation.

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130516.1 | Last Updated 1 Sep 2003
Article Copyright 2003 by Todd C. Gleason
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid