How to implement a multi-index dictionary?

Viewed 11254

Basically I want something like Dictionary<Tkey1, TKey2, TValue>, but not (as I've seen here in other question) with the keys in AND, but in OR. To better explain: I want to be able to find an element in the dictionary providing just one of the keys, not both.

I also think we should consider thread-safety and the ability to easily scale to a Dictionary<Tkey1, TKey2, TKeyN, TValue> solution...

12 Answers

I have written such a dictionary and posted it on my blog. It will give you a nice API like this:

DoubleKeyDictionary<int, string, string> books = new DoubleKeyDictionary<string, string, string>();
bookListEx.Add(1, “21/12/2009″, “Lord of the Rings - Fellowship of the Ring”); 

You can also do "Equals" on two dictionaries and for-each over it.

Please note that there are at least one bug in the code (as discovered in the comments) and no unit tests etc. When (yeah!) I get some time I'll update the code with unit tests...

If your indices are of different types you might want to consider a combination of a SortedList and a Dictionary:

    public SortedList<MyIndexType, MyDataType> PrimaryIndex = new SortedList<MyIndexType, MyDataType>();
    public Dictionary<string, MyDataType> OtherIndex = new Dictionary<string, MyDataType>();

MyIndexType can then implement IComparable:

    class MyIndexType: IComparable
    {
        public DateTime EventTime { get; set; }
        public string Code { get; set; }
        public int CompareTo(object obj)
        {
            MyIndexType otherObject = (MyIndexType)obj;
            if (otherObject.EventTime > this.EventTime)
            { return -1; } //This object preceeds the otherObject
            else if (otherObject.EventTime < this.EventTime)
            { return 1; } //This object is after the otherObject
            else if (otherObject.Code.CompareTo(this.Code) > 0)
            { return -1; } //otherObjecthas code later than me
            else
            { return 1; } //if the Code is the same or greater, put the other one after me
        }
    }
Related