Using collections as key in Dictionary<TKey, TValue>

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • whosaidwhat
    New Member
    • Mar 2010
    • 4

    Using collections as key in Dictionary<TKey, TValue>

    Hello, I am creating a program that has a byte[] used as the key for a Dictionary class. The problem is best described with an example:

    (C# example of problem)
    Code:
            private Dictionary<byte[], string> dictionary;
    
            public void Method1()
            {
                // Set up the dictionary
                dictionary = new Dictionary<byte[], string>();
                byte[] bytes1 = new byte[2] { 0, 0 };
                byte[] bytes2 = new byte[2] { 0, 0 };
                dictionary.Add(bytes1, "hello");
                
                // Search with byte[] 1, the original byte[]
                string result1 = dictionary[bytes1];
                string result2 = getMethod(bytes1);
    
                // Search with byte[] 2, the non-original one
                // These throw errors specifying that the entry does not exist
                string result3 = dictionary[bytes2];
                string result4 = getMethod(bytes2);
            }
    
            private string getMethod(byte[] getBytes)
            {
                return dictionary[getBytes];
            }
    I imagine the Dictionary is searching for the exact reference to the byte[] which was added to the Dictionary, and not just searching for a value match (which is what I want to do).

    Thanks
  • tlhintoq
    Recognized Expert Specialist
    • Mar 2008
    • 3532

    #2
    You haven't actually mentioned or described a problem: Only what you are doing? What is it that you need help with?

    Comment

    • whosaidwhat
      New Member
      • Mar 2010
      • 4

      #3
      I want the Dictionary to be able to search for the key byte[] by the values contained in it. I want bytes2 array (used in my provided example) to match a entry in the Dictionary because its values are contained in a key in the Dictionary.

      Comment

      • tlhintoq
        Recognized Expert Specialist
        • Mar 2008
        • 3532

        #4
        I got the 'want' part.
        What is actually happening? I can guess that it is in *some way* not described not working. But what is it doing?

        I shouldn't have to feel like I'm interegating someone to try to help them. Try volunteering a full description of the problem, the expected behavior versus the actual behavior...

        When you go to the doctor do yo say "I want to be able to walk, you figure the rest out." Or do you say "Every time I step the the left foot there is a shooting pain up the calf."

        Comment

        • whosaidwhat
          New Member
          • Mar 2010
          • 4

          #5
          I do apologize I am having difficulty desribing the problem from a third party point of view and I am assuming too much.

          Referring to the example provided:

          Actual result: "string result3 = dictionary[bytes2];" Throws an error, saying it cannot find the entry.

          Expected result: "string result3 = dictionary[bytes2]; " Returns "hello" and puts it into result3, this is what I want it to do.

          Comment

          • tlhintoq
            Recognized Expert Specialist
            • Mar 2008
            • 3532

            #6
            The problem is with the way you are trying to get the value from a dictionary like it was a simple array.
            Code:
            string result1 = dictionary[bytes1];
            If bytes1 has a value of 5 then dictionary[5] would be the 6th key/value pair entry of the dictionary. There is no 'searching' taking place in what you are trying to do.

            You need to supply the key you are looking for and a string to use as the 'out' variable for the matching value, if one is found
            Originally posted by MSDN
            Code:
            string value = "";
                    if (openWith.TryGetValue("tif", out value))
                    {
                        Console.WriteLine("For key = \"tif\", value = {0}.", value);
                    }
            You should read up on the Dictionary on MSDN to see how to get values returned from the keys you are searching for.

            Comment

            • whosaidwhat
              New Member
              • Mar 2010
              • 4

              #7
              How I am trying to get values from the Dictionary by way of dictionary[KEY] is correct and works. In your example and the examples from MSDN the TKey is a string, or some other non-collection type. With my example the TKey is a byte array, this is what is required in my actual application.

              As I have tried to show in my first example, I can retrive the value for an entry easily when I specify the exact byte[] that I added to the dictionary. If I create the another byte[] with the exact same data, it will not retrive any value.

              I have limited experience in C++ but the problem I am having in C# seems to make more sense in C++. It is like I am telling the Dictionary to store a reference to the byte[] when I add an entry. So when the Dictionary tried to match a TKey (byte[]) with a value, it tries to find the key which matches the specified reference value, rather than matching the contents at the references address.

              This problem only seems to occur when the Key is a collection type, I have tried substituting the byte[] for a List<byte>

              Comment

              • tlhintoq
                Recognized Expert Specialist
                • Mar 2008
                • 3532

                #8
                You may have hit on a bug/limitation of the Dictionary. are your bytes within the acceptable range of ASCII? You could store an ASCII representation of your byte[] IE. a string. It would mean just a little more coding to take your byte array into a string to put it in the dictionary then again when you pull it out.

                Comment

                • clehene
                  New Member
                  • Jun 2010
                  • 1

                  #9
                  IEqualityCompar er

                  @whosaidwhat, you need to supply a comparer to the Dictionary constructor.



                  It's recommended that you extend EqualityCompare r rather than implement the IEqualityCompar er interface.

                  Basically you need to override the Equals and GetHashCode methods.

                  Here's an example of IEqualityCompar er<byte[]>

                  Comment

                  • Plater
                    Recognized Expert Expert
                    • Apr 2007
                    • 7872

                    #10
                    Yes, using a non base Type (things like ints, doubles, strings will work fine) make the dictionary look for the exact instance of the key, not a key with the same "value"

                    Following clehene's advice should get you what you need

                    Comment

                    Working...