Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dictionary with two keys

Tags:

c#

dictionary

What is the best way to index value by two keys in a dictionary. Ex.: having students with unique Id(integer) and username(string) create a dictionary that holds objects of type student indexed by Id and username. Then on a retrieval use either Id or username. Or may be Dictionary is not a good match? P.S. I'm aware of tuples but failing to see how they can be used in this scenario.

EDIT: As an alternative to using two keys, I could create a string representation of both id and username separated by unique divider, and then match keys using regex?! Ex.: "1625|user1"

like image 531
Dimitri Avatar asked Dec 12 '22 22:12

Dimitri


2 Answers

Since you want to be able to retrieve by either, you'll need two dictionaries.

Assuming the Student type is a reference type, you'll still only have one Student object per student, so don't worry about that.

It would be best to wrap the dictionaries in a single object:

public class StudentDictionary
{
  private readonly Dictionary<int, Student> _byId = new Dictionary<int, Student>();
  private readonly Dictionary<string, Student> _byUsername = new Dictionary<string, Student>();//use appropriate `IEqualityComparer<string>` if you want other than ordinal string match
  public void Add(Student student)
  {
    _byId[student.ID] = student;
    _byUsername[student.Username] = student;
  }
  public bool TryGetValue(int id, out Student student)
  {
    return _byId.TryGetValue(id, out student);
  }
  public bool TryGetValue(string username, out Student student)
  {
    return _byUsername.TryGetValue(username, out student);
  }
}

And so on.

like image 59
Jon Hanna Avatar answered Dec 14 '22 10:12

Jon Hanna


You can use two dictionaries you keep in sync, one that maps names to students, and another that maps IDs to students. The easiest way is probably to wrap that in your own class which handles the synchronisation.

like image 20
Joey Avatar answered Dec 14 '22 10:12

Joey