user3544055
user3544055

Reputation: 13

Compare two dictionaries and merge in to other dictionary with keys and values present in both dictionaries

I am working on small utility and as it turns out I have to compare two dictionaries and export the data in Excel in the below format

Key dict1value dict2value

If a key is available in both the dictionaries. My output would be Key dict1value dict2value If a key is available in firstdictionary and not in second . My output would be Key dict1Value "NotAvailable" If a key is available in second dictionary but not in first . My output would be key "Not Available" dict2value.

To be more clear, The key column in Excel consists of keys from both the dictionaries.The value columns will have values depending on the availability.

Though the below code is working,I would like to know if I can optimize the performance even more. Note : Please ignore the bad naming conventions

        public void validateTwoDictionaries()
    {
        Dictionary<string, string> dict1 = new Dictionary<string, string>();
        Dictionary<string, string> dict2 = new Dictionary<string, string>();
        Dictionary<string, KeyValuePair<string, string>> complexdicts = new Dictionary<string, KeyValuePair<string, string>>();

        dict1.Add("A", "1");
        dict1.Add("B", "2");

        dict2.Add("A", "2");
        dict2.Add("C", "3");
        dict2.Add("D", "4");

        int count1 = dict1.Keys.Count;
        int count2 = dict2.Keys.Count;
        int maxcount = count2;
        if (count1 > count2)
        {
            maxcount = count1;

        }

        for (int i = 0; i < maxcount; i++)
        {
            string dict1Key = string.Empty; string dict2Key = string.Empty;
            //need to iterate both the dictionaries at one go.
            if (i < count1)
            {
                dict1Key = dict1.Keys.ElementAt(i);
            }
            if (i < count2)
            {
                dict2Key = dict2.Keys.ElementAt(i);
            }

            // do the work for first dictionary, try to decouple to reuse for the 2nd dict
            if (dict1Key != string.Empty)
            {
                if (!complexdicts.Keys.Contains(dict1Key))
                {
                    if (dict2.Keys.Contains(dict1Key))
                    {
                        // Add to the complext dictionary 
                        complexdicts.Add(dict1Key, new KeyValuePair<string, string>(dict1[dict1Key], dict2[dict1Key]));
                    }
                    else
                    {
                        complexdicts.Add(dict1Key, new KeyValuePair<string, string>(dict1[dict1Key], "Not Available"));
                    }
                }
            }



            // do the work for second dictionary

            if (dict2Key != string.Empty)
            {
                if (!complexdicts.Keys.Contains(dict2Key))
                {
                    if (dict1.Keys.Contains(dict2Key))
                    {
                        // Add to the complext dictionary 
                        complexdicts.Add(dict2Key, new KeyValuePair<string, string>(dict1[dict2Key], dict2[dict2Key]));
                    }
                    else
                    {
                        complexdicts.Add(dict2Key, new KeyValuePair<string, string>("Not Available", dict2[dict2Key]));
                    }
                }
            }
        }

dict1 and dict2 are sample dictionaries and complexdicts object is what I want to export to excel. Please let me know if I can do this in better way.

Upvotes: 0

Views: 489

Answers (2)

Elyse
Elyse

Reputation: 1

How about this?

Dictionary<string, string> dict1 = new Dictionary<string, string>();
Dictionary<string, string> dict2 = new Dictionary<string, string>();

dict1.Add("A", "1");
dict1.Add("B", "2");

dict2.Add("A", "2");
dict2.Add("C", "3");
dict2.Add("D", "4");

var allKeys = dict1.Keys.Union(dict2.Keys);

// case 1
List<Tuple<string, string, string>> unionValues = new List<Tuple<string, string, string>>();
foreach (var key in allKeys)
{
    unionValues.Add(new Tuple<string, string, string>(key, dict1.ContainsKey(key) ? dict1[key] : "N/A" , dict2.ContainsKey(key) ? dict2[key] : "N/A"));
}

// case 2
var result = (from key in allKeys
             select new Tuple<string, string, string>(key, dict1.ContainsKey(key) ? dict1[key] : "N/A", dict2.ContainsKey(key) ? dict2[key] : "N/A")).ToList();

Upvotes: 0

Sriram Sakthivel
Sriram Sakthivel

Reputation: 73472

How about this?

Dictionary<string, string> dict1 = new Dictionary<string, string>();
Dictionary<string, string> dict2 = new Dictionary<string, string>();
Dictionary<string, KeyValuePair<string, string>> complexdicts = new Dictionary<string, KeyValuePair<string, string>>();

dict1.Add("A", "1");
dict1.Add("B", "2");

dict2.Add("A", "2");
dict2.Add("C", "3");
dict2.Add("D", "4");

var allKeys = dict1.Keys.Union(dict2.Keys);

foreach (var key in allKeys)
{
    string val1;
    if (!dict1.TryGetValue(key, out val1))
    {
        val1 = "Not Available";
    } 
    string val2;
    if (!dict2.TryGetValue(key, out val2))
    {
        val2 = "Not Available";
    }
    complexdicts.Add(key, new KeyValuePair<string, string>(val1, val2));
}

Upvotes: 3

Related Questions