【问题标题】:Efficiently Merging Lists of Lists有效地合并列表列表
【发布时间】:2011-08-26 15:54:58
【问题描述】:

我需要一些帮助来开发一种算法,该算法基于键/值对的匹配来合并列表列表。

在下面的示例中,我有 3 个 List> 实例,我想使用 Merge 方法调用来减少/合并它们。 Merge 的目的是获取包含任何匹配键/值对的实例,并将两个列表合并到一个新列表中,该列表包含两个列表中的所有对。所以在这个例子中,Merge 方法应该将 3 个列表压缩为 1 个,因为 list1 和 list2 都包含匹配的键名和“key1”和“key2”的值。然后新合并的 list1 和 list2 列表将进一步与 list3 合并,因为它们都包含匹配的键名和“key4”的值。

有人对高效算法有任何想法吗?我目前正在使用一种非常慢的递归方法,因为它将每个列表与其他每个列表进行比较。

    var list1 = new List<KeyValuePair<string, string>> { 
        new KeyValuePair<string,string>("key1","2"), 
        new KeyValuePair<string,string>("key2","5"),
        new KeyValuePair<string,string>("key3","20")
    };

    var list2 = new List<KeyValuePair<string, string>> { 
        new KeyValuePair<string,string>("key1","2"), 
        new KeyValuePair<string,string>("key2","5"),
        new KeyValuePair<string,string>("key4","10"),
        new KeyValuePair<string,string>("key5","A"),
        new KeyValuePair<string,string>("key6","B"),
        new KeyValuePair<string,string>("key7","C")
    };

    var list3 = new List<KeyValuePair<string, string>> { 
        new KeyValuePair<string,string>("key10","2"), 
        new KeyValuePair<string,string>("key20","5"),
        new KeyValuePair<string,string>("key4","10"),
        new KeyValuePair<string,string>("key40","2")
    };

    var fullList = new List<IList<KeyValuePair<string, string>>>();

    fullList.Add(list1); 
    fullList.Add(list2); 
    fullList.Add(list3);

    List<IList<KeyValuePair<string, string>>> mergedList = fullList.Merge();

    /*
     output should be a single a single IList<KeyValuePair<string, string>> with a count of 10 KeyValuePair<string,string> items
     mergedList would contain the following key/value pairs

        "key1","2" 
        "key2","5"
        "key3","20"
        "key4","10"
        "key5","A"
        "key6","B"
        "key7","C"
        "key10","2" 
        "key20","5"
        "key40","2"
    */

【问题讨论】:

  • 可以直接使用HashSet.Union还是自己实现?
  • 在 KVP 中键匹配但值不同的情况下怎么办?
  • @Nicholas - 如果 kays 匹配但值不同,则不应发生合并。我只希望在比较中的 2 个目标列表中所有共享键具有相同值时合并
  • @dotjoe - 当所有相交的键具有相同的值时,HashSet.Union 会合并吗?
  • 哦,只需覆盖 Equals 以说明键和值...那么您应该让 HashSet 进行联合。

标签: c# algorithm .net-4.0


【解决方案1】:

【讨论】:

  • 我基本上在使用这样的实现,但它似乎很慢。
  • 您的列表有多大?我建议内置的 LINQ 实现会比你自己构建的更快。
【解决方案2】:

看起来您可以使用Dictionary&lt;String, HashSet&lt;String&gt;&gt; 来存储合并的数据。这将允许您快速查找输出是否已经包含您想要的键,如果没有添加它(并且,对于它的值,包含当前项目值的哈希集)。如果键已经存在于字典中,只需获取值(一个哈希集)并调用它的 Add 方法,该方法已经有效地防止重复。

【讨论】:

    【解决方案3】:

    听起来您想将描述中的三个列表合并,而不是获取列表列表,例如

    var list1 = new List<KeyValuePair<string, string>> { 
            new KeyValuePair<string,string>("key1","2"), 
            new KeyValuePair<string,string>("key2","5"),
            new KeyValuePair<string,string>("key3","20")
        };
    
    var list2 = new List<KeyValuePair<string, string>> { 
            new KeyValuePair<string,string>("key1","2"), 
            new KeyValuePair<string,string>("key2","5"),
            new KeyValuePair<string,string>("key4","10"),
            new KeyValuePair<string,string>("key5","A"),
            new KeyValuePair<string,string>("key6","B"),
            new KeyValuePair<string,string>("key7","C")
        };
    
    var list3 = new List<KeyValuePair<string, string>> { 
            new KeyValuePair<string,string>("key10","2"), 
            new KeyValuePair<string,string>("key20","5"),
            new KeyValuePair<string,string>("key4","10"),
            new KeyValuePair<string,string>("key40","2")
        };
    
    var unionedList = new List<KeyValuePair<string, string>>();
    
    unionedList.AddRange(list1.Union(list2).Union(list3));
    
    foreach (var kvp in unionedList)
    {
        Console.WriteLine(string.Format("{0} {1}", kvp.Key, kvp.Value));    
    }
    

    unionedList 现在将根据您的预期输出包含不同的 KeyValue 对列表。如果值不同,您将获得重复的键。

    【讨论】:

      猜你喜欢
      • 2016-02-08
      • 2014-01-26
      • 1970-01-01
      • 2012-09-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多