views:

92

answers:

2

Hello all

I have two complex dictionaries in the form

Dictionary<string, Dictionary<string, Dictionary<string, List<string>>>>

So as you see i've inner dictionaries. I want to write a generic recursive function which can merge two complex dictionaries of this form (or any other complex form of dictionaries), by calling itself passing the inner dictionaries (which are of different structure). This question also has another part. How to append one dictionary to other without looping?

A bit more explanation

This dictionary holds LIST OF MESSAGES sent BY A USER chatting in a SPECIFIC GROUP CHAT SESSION to a SPECIFIC USER (read the sentence and interpret the dictionary from the end). So i've two dictionaries of this form. As soon as i dispatch the message to a user i remove it from the dictionary. But i want to have history of messages. So before removing it i just make a copy by appending it to another dic which contains all the messages, in all chat sessions, from all users, to all users till now!

Note: I'm not blessed to use LINQ.

Thank you

NLV

+1  A: 

Runtime dispatching based on type has to use reflection, which is very messy when generics come into play. I recommend "cheating" and using IDictionary instead.

So, your method declaration would look something like this:

// Merges b into a
void Merge<T>(T a, T b) where T : IDictionary

Then, iterate through each entry of b. If the key does not exist in a, then add the kvp to a and continue iterating. If the value is IDictionary, then pass the a value and b value to Merge recursively. Otherwise, if it is ICollection, then merge its values into the collection in a. Otherwise, error.

Stephen Cleary
+2  A: 

If I dare be so bold, using dictionaries in this manner makes for extremely unmaintainable code.

IMHO, The following class structure, or similar, would be much, much easier to understand and work with.

public class User {
  public string Name {get;set;}

  // Sessions this user is participating in
  // (when you add to Session, add here too - Using a method to add both at same would be safest)
  public List<Session> Sessions {get;set;}

  // etc
}

public class Message {
  public User Sender {get;set;}
  public string Text {get;set;}
  // etc
}

public class Session {
  public string Title {get;set;}
  public List<User> Participants {get;set;}
  public List<Message> SentMessages {get;set;}
  public List<Message> UnsentMessages {get;set;}
}

public class ChatSystem {
   // All Users - Indexed by Name
   public Dictionary<string, User> Users {get; set;}

   // All Sessions - Indexed by Title
   public Dictionary<string, Session> Sessions {get; set;}
}

I know this isn't addressing your specific request, but is attempting to address the essence of the request - being able to work with Users, Chat Sessions and Messages easily.

Have fun!

Will
Absolutely right. Accepted. But i'm long way in to change the code now :(
NLV
Okie. If i create custom classes like this how can i easily search a user or a message or a group chat id? It will be tough. Can i do it without looping? Just because i have it in the dictionary format i'm able to make use of all the useful dictionary functions.
NLV
I've edited my reply to handle searching by User or Session. Hope it helps... (oh, and corrected mix of C#/VB *blush*)
Will