Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to combine 2 ints to make a unique dictionary key

Tags:

c#

dictionary

key

I am trying to make a dictionary key from 2 ints, I am thinking to combine them as follows 2 and 3 ---> 23 21 and 34 ---> 2134 etc etc

How would one acheive this, and if this is a bad approach, what would be better?

Thanks in advance

like image 271
KMoore Avatar asked Oct 26 '25 14:10

KMoore


1 Answers

The following struct combines two integers and overrides equality members to make it usable as key in a dictionary. This solution is faster than my previous proposal using a Tuple<T1,T2> and less error prone than using a long.

public struct IntKey
{
    private readonly int first;
    private readonly int second;

    public int First { get { return first; } }
    public int Second { get { return second; } }

    public IntKey(int first, int second)
    {
        this.first = first;
        this.second = second;
    }

    public bool Equals(IntKey other)
    {
        return this.first == other.first && this.second == other.second;
    }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj))
        {
            return false;
        }
        return obj is IntKey && Equals((IntKey) obj);
    }

    public override int GetHashCode()
    {
        unchecked
        {
            return (this.first*397) ^ this.second;
        }
    }
}

[TestClass]
public class DictionaryTests
{
    [TestMethod]
    public void Test()
    {
        var dictionary = new Dictionary<IntKey, string>();

        for (int j = 0; j < 3; j++)
        {
            dictionary.Clear();
            var watch = Stopwatch.StartNew();

            for (int i = 0; i < 1000000; i++)
            {
                dictionary.Add(new IntKey(i, i), "asdf");
            }

            Console.WriteLine(watch.ElapsedMilliseconds);
            watch.Restart();

            for (int i = 0; i < 1000000; i++)
            {
                var value = dictionary[new IntKey(i, i)];
            }

            Console.WriteLine(watch.ElapsedMilliseconds);
        }
    }
}

Try it. 1,000,000 writes or reads take about 250ms on my Azure VM.

like image 182
Frank Avatar answered Oct 29 '25 02:10

Frank