Subscribe RSS 2.0 cshandler feeds

Tuesday, 29 January 2013

Lookup A Dictionary with duplicate key value pairs

Have you ever felt a requirement of duplicate keys and value pairs in a dictionary? Sounds like crazy!!! But yes few days back I required to have a map/dictionary with multiple entries of same key with different values and then performing some operation like groupby and get the count blah.. blah...

So I couldn’t use the Dictionary object to fulfill my requirement as below is what you’ll get if you try to insert multiple keys inside a normal Dictionary object:

image

So googled around and finally endup reading a post of JonSkeet explaining how we can utilize LookUp for this problem. Well I got enlighten after reading the awesome post and decided to explore the Lookup class and its usage.

Well in the screenshot you can see that you can not insert duplicate entries in a Dictionary class so you do need a custom list to store those values. Here’s the sample code where I’ve crated a simple data class that is holding my key and value pairs.

  1. public class Data
  2. {
  3.     public string Key { get; set; }
  4.     public int Value { get; set; }
  5. }

Now you can use a List<Data> to store those items in this:

  1. List<Data> keyValuePairs = new List<Data>();
  2. keyValuePairs.Add(new Data { Key = "key1", Value = 1 });
  3. keyValuePairs.Add(new Data { Key = "key1", Value = 1 });
  4. keyValuePairs.Add(new Data { Key = "key2", Value = 3 });
  5. keyValuePairs.Add(new Data { Key = "key3", Value = 4 });
  6. keyValuePairs.Add(new Data { Key = "key3", Value = 5 });
  7. keyValuePairs.Add(new Data { Key = "key4", Value = 6 });

But this is not actual key value pair collection that we needed. So, you all familiar with the LINQ and its Extension methods on any IEnumerable. Just checkout the ToLookup function, this is what we’ll use to convert this list to an key value pair collection.

  1. var groupedData = keyValuePairs.ToLookup(x => x.Key, x => x.Value);

Now we have this groupedData collection which is of type IGroupInfo<string, int> in our case. so we can apply the grouping operations and find the multiple values related to a Key.

  1. foreach (IGrouping<string, int> item in groupedData)
  2.             {
  3.                 Console.Write(item.Key);
  4.                 Console.Write(": ");
  5.                 foreach (var value in item)
  6.                 {
  7.                     Console.Write(value + " ");
  8.                 }
  9.                 Console.WriteLine();
  10.             }

When you run this program you’ll get the output:

image

Beautiful !! isn’t it? We got all the keys and corresponding values in place.

you can ask, If it’s a dictionary then Would I be able to get the values corresponding to a key using indexer? Answer is: YES.

Go ahead and use indexer of keys and get all the values as IEnumerable. Check this out:

  1. Console.Write("Key3: ");
  2. foreach (var value in groupedData["key3"])
  3. {
  4.     Console.Write(value + " ");
  5. }

Output:

image

This was my first encounter with Lookup and I liked it. Hope you do feel the same.

Mug Cheers!!

3 comments:

  1. Ya.....nice one Bro keep it up...:)

    ReplyDelete
  2. Why not use NameValueCollection?

    ReplyDelete
  3. and order of this search is different from order of normal dictionary search ?

    ReplyDelete