Wednesday, September 9, 2009

Dictionary Class in C#

Dictionary Class in C#

One of the nice things about the rich library of classes in most object-oriented programming languages is that you aren't having to reinvent the wheel every time. Here's yet another example. One of my readers noticed that the link audit tool doesn't handle URL decoding of stuff like & or -. To handle the first category, called "named entities" I needed a way to convert a long list of strings to a corresponding value.

In C (and most other procedural languages), you would do this with either a series of if...else if... statements (ugly and slow), or you end up defining a structure that contains a string and a number, and then an array of those structures, then a function that searched through that array, finding a matching string. I can't even begin to count the number of times over the years that I have written code like this. If you are half-clever, you reuse the function with different arrays.

Here's the equivalent using the Dictionary class:


private static Dictionary namedEntities = new Dictionary
{
{"amp", (short)'&'},
{"nbsp", 160},
{"cent", 162},
{"pound", 163},
{"curren", 164},
{"yen", 165},
{"brvbar", 166},
{"sect", 167},
{"uml", 168},
{"copy", 169},
{"ordf", 170},
{"laquo", 171},
{"not", 172},
{"shy", 173},
{"reg", 174},
{"macr", 175},
{"deg", 176},
{"plusmn", 177},
{"sup2", 178},
{"sup3", 179},
{"acute", 180},
{"micro", 181},
{"para", 182},
{"middot", 183},
{"cedil", 184},
{"sup1", 185},
{"ordm", 186},
{"raquo", 187},
{"frac14", 188},
{"frac12", 189},
{"frac34", 190},
{"iquest", 191},
{"Agrave", 192},
{"Aacute", 193},
{"Acirc", 194},
{"Atilde", 195},
{"Auml", 196},
{"Aring", 197},
{"AElig", 198},
{"Ccedil", 199},
{"Egrave", 200},
{"Eacute", 201},
{"Ecirc", 202},
{"Euml", 203},
{"Igrave", 204},
{"Iacute", 205},
{"Icirc", 206},
{"Iuml", 207},
{"Ntilde", 209},
{"Ograve", 210},
{"Oacute", 211},
{"Ocirc", 212},
{"Otilde", 213},
{"Ouml", 214},
{"times", 215},
{"Oslash", 216},
{"Ugrave", 217},
{"Uacute", 218},
{"Ucirc", 219},
{"Uuml", 220},
{"Yacute", 221},
{"szlig", 223},
{"agrave", 224},
{"aacute", 225},
{"acirc", 226},
{"atilde", 227},
{"auml", 228},
{"aring", 229},
{"aelig", 230},
{"ccedil", 231},
{"egrave", 232},
{"eacute", 233},
{"ecirc", 234},
{"euml", 235},
{"igrave", 236},
{"iacute", 237},
{"icirc", 238},
{"iuml", 239},
{"eth", 240},
{"ntilde", 241},
{"ograve", 242},
{"oacute", 243},
{"ocirc", 244},
{"otilde", 245},
{"ouml", 246},
{"divide", 247},
{"oslash", 248},
{"ugrave", 249},
{"uacute", 250},
{"ucirc", 251},
{"uuml", 252},
{"yacute", 253},
{"thorn", 254},
{"yuml", 255}
};

...

short namedEntityValue;
string namedEntityString;

// get the string from the URL and put it into namedEntityString

...

if (namedEntities.TryGetValue(namedEntityString, out namedEntityValue))
{
// if the namedEntityString was in the namedEntities dictionary, namedEntityValue
// now has the corresponding value
}
else
{
// didn't find a match in the dictionary
}


Some examples of how to use Dictionary use:


if (namedEntities.ContainsKey(namedEntityString))
{
namedEntityValue = namedEntities[namedEntityString];
}

This works, but it is inefficient, because you are doing the lookup twice (at least, assuming that namedEntityString is present in namedEntities). Using TryGetValue method makes one call. Of course, inside of TryGetValue you are still performing the same operations as the call to ContainsKey and then the index into namedEntities, but it is likely to be more efficiently coded inside this method than as two separate C# lines.

No comments:

Post a Comment