简体   繁体   中英

C# Dealing with Dictionaries

I'm new working with c#, i have experience working with c++ and java. I'm trying to mess around with dictionaries but i cant really get this to work. I have two arrays the data type have to be objects, after i add them to two different dictionaries im trying to find a key within, but i cant get it to go into the if statements.Which of the two declarations of dictionary is correct dictionary1 or dictionary2? Also how can i find a value by the key or a key by the value in the correct dictionary or both.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Practice_With_Dictionaries
{
    class Program
    {
        static void Main(string[] args)
        {


                object[] array1 = new object[5];
                array1[0] = "1111";
                array1[1] = "2222";
                array1[2] = "3333";
                array1[3] = "4444";
                array1[4] = "5555";

                object[] speed = new object[5];
                speed[0] = 1;
                speed[1] = 2;
                speed[2] = 3;
                speed[3] = 4;
                speed[4] = 5;

                object[] keys = new object[1];
                keys[0] = (object[])array1;

                object[] speedTable = new object[1];
                speedTable[0] = (object[])speed;


                Dictionary<object, object> dictionary1 = new Dictionary<object, object>();
                Dictionary<object[], object[]> dictionary2 = new Dictionary<object[], object[]>();


                dictionary1.Add(keys, speedTable);
                dictionary2.Add(keys, speedTable);

                if (dictionary1.ContainsKey((object)"1111"))
                {
                    var method = 1;
                }

                if (dictionary2.ContainsKey(array1))
                {
                    var method = 2;
                }



        }
    }
}

dictionary1.ContainsKey((object)"1111") will never return true because "1111" will be boxed into a new unique object every time.

Populate one item at a time

You can populate the dictionary one item at a time:

    Dictionary<object, object> dictionary1 = new Dictionary<object, object>();

    for (int i = 0; i < array1.Length; i++)
    {
        dictionary1.Add(array1[i], speed[i]);
    }

    object key1 = array1[0];

    if (dictionary1.ContainsKey(key1))
    {
        var method = 1;
    }

Populate using LINQ

You can also populate the dictionary without explicit loops using LINQ and the ToDictionary(IEnumerable<TSource, Func<TSource, TKey>, Func<TSource, TElement>) method, which creates a Dictionary from an IEnumerable according to specified key selector and element selector functions.

Dictionary<object, object> dictionary2 = array1
    .Select((obj, index) => new KeyValuePair<object, object>(array1[index], speed[index]))
    .ToDictionary(kvp => kvp.Key, kvp => kvp.Value);

Dictionary<object, object> dictionary3 = array1
    .Select((obj, index) => index)
    .ToDictionary(i => array1[i], i => speed[i]);

Dictionary<object, object> dictionary4 = Enumerable.Range(0,5)
    .ToDictionary(i => array1[i], i => speed[i]);

The challenge with your code is that you are passing key values in a form of array or in others, they are using a list. Usually we initialize a Dictionary in a one to one relationship:

Dictionary<object, object> dict = new Dictionary<object, object>();

Sometimes in a one to many relationship:

Dictionary<object, object[]> dict = new Dictionary<object, object[]>();

In your case, you initialize it on a many to many relationship:

Dictionary<object[], object[]> dictionary2 = new Dictionary<object[], object[]>();

Although on your first example, particularly dictionary1, you still pass an array on your TKey value (see your code):

Dictionary<object, object> dictionary1 = new Dictionary<object, object>();
dictionary1.Add(keys, speedTable); //the value of keys consists of an object of an array: keys[0] = (object[])array1;

So your best shot is to implement your Dictionary with TKey of a single object, and TValue of an object or an array of object or a list of objects.

If you still want to do an array of object, you need to implement a custom IEqualityComparer since you cannot do what you are trying to do in your if statements.

Here is a sample generic implementation, you need to supply IEqualityComparer in your constructor Dictionary:

 public class DictionaryComparer<T> : IEqualityComparer<List<T>>
 {
    public bool Equals(List<T> x, List<T> y)
    {
        //TODO: Your implementation for your contains or equals condition
    }

    public int GetHashCode(List<T> obj)
    {
      //TODO: Implementation of your GetHashCode
    }
 }

Then implement it:

 if (new DictionaryComparer<object>().Equals(lstCompare, lstCompareTo))
   {
          //TODO: Your condition here..
   }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM