【问题标题】:Remove duplicate comparing two large lists efficiently in C#?在 C# 中有效地删除重复比较两个大列表?
【发布时间】:2014-11-12 17:55:32
【问题描述】:

我有两个大列表,list1 有 4 列,list2 有 3 列。 如果 list1 在第 1 列和第 3 列中包含与 list2 相同的值,那么我需要在 list1 中删除该项目。我实际上正在寻找一些优势和有效的解决方案。感谢您的帮助。

List1:
1, 5, 3, 9     // Remove this
11, 15, 18, 6  // Keep this  

List2:
1, 5, 3

List<Tuple<int, int, int, int>> list1 = new List<Tuple<int, int, int, int>>();
List<Tuple<int, int, int>> list2 = new List<Tuple<int, int, int>>();

【问题讨论】:

  • 代码中列的列表如何表示?
  • 那么您是否要删除 List1 和 List2 中包含的所有元素?还是有什么逻辑?
  • 嗯,这只是逻辑,但两个列表不一样,一个有 4 列,另外 3 列。

标签: c# linq


【解决方案1】:

理想情况下,从性能角度来看,您可以利用 HashSet.SymmetricExceptWith,但您使用的是两种不同的类型(以及 Tuples)。

Except 是一个可能的解决方案:

list1 = list1.Except(list1
    .Where(l1 => list2
        .Any(l2 => l2.Item1 == l1.Item1
            && l2.Item2 == l1.Item2
            && l2.Item3 == l1.Item3)))
    .ToList();

【讨论】:

  • 我试过了,但我不知道为什么它不起作用。错误:无法将类型 'System.Collections.Generic.IEnumerable>' 隐式转换为 'System.Collections.Generic.List>'
  • @doro 检查编辑,最后缺少.ToList()
  • 完美!我喜欢这个,因为它简单干净。
【解决方案2】:
        var index2 = list2.ToLookup(t => Tuple.Create(t.Item1, t.Item3));
        //var index2 = list2.Select(l => Tuple.Create(l.Item1, l.Item3)).ToList();
        //index2.Sort();
        var results = from l in list1
                      where !index2.Contains(Tuple.Create(l.Item1, l.Item3))
                      select l;

这可能会相当有效。缺点是 index2 使用了额外的内存。注释掉了另一种在内存上更容易的索引方法。 ToList 版本不会存储对您的原始记录的引用,因此它会更轻量级。但是 ToLookup 索引对您来说可能比这个特定问题有更多的用途。如果每个键都是唯一的,那么 ToDictionary 也将是一个选项,而不是 ToLookup,但这是对重量级的倒退。

根据这些列表的实际大小,通过几个放置良好的 AsParallel() 调用可能会获得额外的收益。

        var index2 = list2.AsParallel().ToLookup(t => Tuple.Create(t.Item1, t.Item3));
        var results = from l in list1.AsParallel()
                      where !index2.Contains(Tuple.Create(l.Item1, l.Item3))
                      select l;

用其中一种或另一种或两者进行实验,因为只有您的环境才能告诉我们这是否是最好的。有时,将工作拆分到多个线程上花费的时间可能比连续完成工作要长。

【讨论】:

  • 感谢您的 2 个版本。
猜你喜欢
  • 2011-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-17
  • 2015-01-17
  • 1970-01-01
相关资源
最近更新 更多