【问题标题】:Compare two dictionaries and merge in to other dictionary with keys and values present in both dictionaries比较两个字典并合并到另一个字典中,两个字典中都存在键和值
【发布时间】:2014-04-17 15:50:12
【问题描述】:

我正在研究小型实用程序,事实证明我必须比较两个字典并以以下格式导出 Excel 中的数据

键 dict1value dict2value

如果两个字典中都有一个键。我的输出是 键 dict1value dict2value 如果一个键在 firstdictionary 而不是 second 中可用。我的输出是 键 dict1Value "NotAvailable" 如果 key 在 second 字典中可用,但在 first 中不可用。我的输出是 键“不可用”dict2value。

更清楚地说,Excel 中的键列由两个字典中的键组成。值列的值取决于可用性。

虽然下面的代码可以工作,但我想知道我是否可以进一步优化性能。 注意:请忽略错误的命名约定

        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 和 dict2 是示例字典,而 complexdicts 对象是我要导出到 excel 的对象。 如果我能以更好的方式做到这一点,请告诉我。

【问题讨论】:

  • 这是一个字典,所以键必须是唯一的,将它们命名为"Not Available" 将用于第一个,而不是之后的。
  • 我在您的描述中发现了一个问题:如果它们是 dic2 中但不在 dic1 中的 2 个值,您将如何管理?您不能有 2 个 Not Available 键。你真的想要一个字典作为输出,还是一个元组可以?
  • 很抱歉我应该说清楚。搜索过滤器是 Key 但不是 value。
  • 我必须检查 LINQ 的性能是否更好,但是您可以将 .Concat 与 .GroupBy 结合使用来加入两个字典,这将非常具有可读性和优雅性。在这里看到:stackoverflow.com/questions/10034867/…
  • 我尝试使用 linq。但我不擅长那些东西。但这个链接肯定有帮助。会检查

标签: c# dictionary


【解决方案1】:

这个怎么样?

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));
}

【讨论】:

  • 这绝对比我的更好更简单。谢谢。
【解决方案2】:

这个怎么样?

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();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-03
    • 2017-07-06
    • 2019-05-16
    • 2021-03-30
    相关资源
    最近更新 更多